xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -317,7 +317,7 @@ if (uid == null) { return 0; } Long num = baseMapper.selectCount(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getAppUserId, uid).eq(XpAppUserCoupon::getStatus, 1).lt(XpAppUserCoupon::getExpirationTime, LocalDateTime.now())); Long num = baseMapper.selectCount(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getAppUserId, Long.valueOf(uid)).eq(XpAppUserCoupon::getStatus, 1).lt(XpAppUserCoupon::getExpirationTime, LocalDateTime.now())); return num.intValue(); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java
@@ -57,7 +57,16 @@ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime failureTime; //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}] /** * 自定义时 选择每天只能有一个运营策略 * type = 0工作日 1法定节假日 2非工作日 3自定义时间 typeStr 代表周 = [1,2,3,4,5,6,7] typeStr= 0的时候代表每天 * [{"name": "策略组1", "time": ["09:00-18:00"], "type": 0, "typeStr": []}, * {"name": "策略组2", "time": ["08:00-21:00"], "type": 2, "typeStr": []}, * {"name": "策略组3", "time": ["07:00-22:00"], "type": 1, "typeStr": []}, * {"name": "策略组4", "time": ["12:00-19:00"], "type": 3, "typeStr": [1, 3, 5, 7]}] * * [{"name": "策略组1", "time": ["08:00-22:00"], "type": 3, "typeStr": [0]}] */ @ApiModelProperty(value = "运营策略") private String operationStrategy; @ApiModelProperty(value = "城市code") @@ -74,6 +83,9 @@ @ApiModelProperty(value = "点位数量") @TableField(exist = false) private Long pointCount; @ApiModelProperty(value = "点位运营数量") @TableField(exist = false) private Long fenceAreaPointCount; @ApiModelProperty(value = "场站数量") @TableField(exist = false) private Long stationCount; xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
@@ -167,15 +167,25 @@ @ApiModelProperty(value = "状态描述") @TableField(exist = false) private String hoverStatusDes; @ApiModelProperty(value = "场站的生效时间") @ApiModelProperty(value = "围栏的生效时间") @TableField(exist = false) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime electronicEffectTime; //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}] @ApiModelProperty(value = "围栏运营策略") @TableField(exist = false) private String fenceOperationStrategy; @ApiModelProperty(value = "场站运营类型 1=与运营区同步 2=自定义时间段") @TableField(exist = false) private Integer stationOperationType; @ApiModelProperty(value = "生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日") @TableField(exist = false) private Integer stationEffectivePeriod; @ApiModelProperty(value = "场站运营策略") @TableField(exist = false) private String electronicOperationStrategy; private String stationEffectiveTimePeriod; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpStation.java
@@ -105,7 +105,8 @@ private Integer effectivePeriod; /** * 数据结构 [{"endTime": "18:00", "startTime": "05:00"}] * 数据结构 * ["06:00-12:00", "13:00-21:00"] */ @ApiModelProperty(value = "生效时间段 json") private String effectiveTimePeriod; @@ -136,4 +137,11 @@ @ApiModelProperty(value = "运营中点位数") @TableField(exist = false) private Integer operatingPointCount; @ApiModelProperty(value = "围栏运营策略") @TableField(exist = false) private String fenceOperationStrategy; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListListQuery.java
@@ -1,10 +1,12 @@ package com.xiaopeng.api.query.operation; import com.baomidou.mybatisplus.annotation.TableField; import com.xiaopeng.common.core.web.page.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; @Data @@ -46,5 +48,27 @@ @ApiModelProperty(value = "stationIds") private List<String> stationIds; @ApiModelProperty(value = "电子围栏id") private Long electronicId; @ApiModelProperty(value = "所属场站id,为空表示运营区直属点位") private Long stationId; @ApiModelProperty(value = "点位类型 1=运营点位 2=测试点位") private Integer pointType; @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效") private Integer operationStatus; @ApiModelProperty(value = "电子围栏区域id") private Boolean electronicAreaIdNotNull; @ApiModelProperty(value = "经度") @NotNull(message = "经度不能为空") private Double longitude; @ApiModelProperty(value = "纬度") @NotNull(message = "纬度不能为空") private Double latitude; @ApiModelProperty(value = "距离") private Integer orderDistance; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpStationQuery.java
@@ -9,6 +9,9 @@ @Data public class XpStationQuery extends BasePage { @ApiModelProperty(value = "id") private Long id; @ApiModelProperty(value = "ids") private List<Long> ids; @@ -42,6 +45,8 @@ @ApiModelProperty(value = "更新结束时间") private String updateEndTime; @ApiModelProperty(value = "场站点位数量") private String stationPointNum; @ApiModelProperty(value = "限停时长") private Integer parkingTimeLimitMin; xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/MultiRouteAndFareVo.java
@@ -30,4 +30,6 @@ @ApiModelProperty("价格变动超过该百分比则提示路况变化(如 5 表示 5%)") private Double priceWaveThresholdPercent; @ApiModelProperty(value = "是否开启试运营(0=否,1=是)") private Integer operateFree; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteOptionVo.java
@@ -14,6 +14,8 @@ @ApiModel("合并后的路线选项") public class RouteOptionVo { @ApiModelProperty(value = "是否开启试运营(0=否,1=是)") private Integer operateFree; @ApiModelProperty("路径唯一标识(高德 routeID)") private String pathFingerprint; xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpStationVo.java
@@ -1,10 +1,12 @@ package com.xiaopeng.api.vo.operation; import com.fasterxml.jackson.annotation.JsonFormat; import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.api.model.operation.XpStation; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; import java.util.List; @@ -16,4 +18,19 @@ private List<XpPoint> xpPointList; @ApiModelProperty(value = "生效类型 1=立即生效 2=定时生效") private Integer fenceEffectType; @ApiModelProperty(value = "生效时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime fenceEffectTime; @ApiModelProperty(value = "失效类型 1=永不失效 2=定时失效") private Integer fenceFailureType; @ApiModelProperty(value = "失效时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime fenceFailureTime; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpPointsListVo.java
@@ -1,5 +1,6 @@ package com.xiaopeng.api.vo.order; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -37,8 +38,6 @@ @ApiModelProperty("电子围栏区域id") private Long electronicAreaId; @ApiModelProperty("运营类型 1=与运营区同步 2=自定义时间段") private Integer operationType; @ApiModelProperty("是否收藏 1=是 2=否") private Integer isCollect = 2; @@ -49,6 +48,8 @@ @ApiModelProperty("点位在场站内排序") private Integer stationSortNo; @ApiModelProperty("运营类型 1=与运营区同步 2=自定义时间段") private Integer operationType; @ApiModelProperty("生效周期") private Integer effectivePeriod; @@ -61,6 +62,22 @@ @ApiModelProperty(value = "停车时长") private Integer time; //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}] @ApiModelProperty(value = "围栏运营策略") @TableField(exist = false) private String fenceOperationStrategy; @ApiModelProperty(value = "场站运营类型 1=与运营区同步 2=自定义时间段") @TableField(exist = false) private Integer stationOperationType; @ApiModelProperty(value = "生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日") @TableField(exist = false) private Integer stationEffectivePeriod; @ApiModelProperty(value = "场站运营策略") @TableField(exist = false) private String stationEffectiveTimePeriod; @ApiModelProperty("场站子点位列表") private List<XpPointsListVo> children; } xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java
@@ -50,6 +50,12 @@ * @param endTimeStr 结束时间,格式:"HH:mm" 或 "HH:mm:ss" * @return 如果在时间段内返回true,否则返回false */ public static boolean isCurrentTimeInRange(LocalTime localTime,String startTimeStr, String endTimeStr) { LocalTime startTime = LocalTime.parse(fixTimeFormat(startTimeStr)); LocalTime endTime = LocalTime.parse(fixTimeFormat(endTimeStr)); return !localTime.isBefore(startTime) && localTime.isBefore(endTime); } public static boolean isCurrentTimeInRange(String startTimeStr, String endTimeStr) { LocalTime now = LocalTime.now(); LocalTime startTime = LocalTime.parse(fixTimeFormat(startTimeStr)); xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java
@@ -145,6 +145,17 @@ if(xpVehicle== null){ throw new ServiceException("获取行驶中的车辆信息错误"); } //剩余里程xx米,或者 剩余时间xx分钟 禁止修改目的地 //获取订单的 Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(uid)); if(cacheObject != null){ RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); Integer xczSyDistance = routeRemain.getDistance();//行程中剩余里程 Integer xczSyTime = routeRemain.getDuration();//行程中剩余时间 if(systemSetting.getXczSyDistance()<xczSyDistance || systemSetting.getXczSyTime() < xczSyTime){ throw new ServiceException("即将达到终点,禁止修改目的地"); } } // 是否在运营区域时间内 XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(order.getXpElectronicFenceAreaId()); @@ -183,6 +194,7 @@ //获取距离和时间 this.getDD(uid,dto); //将修改信息存入到redis, // 获取起点经纬度 XpPoint xpPoint = xpPointService.getById(order.getStartPointId()); xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -1037,6 +1037,13 @@ throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND); } XpSystemSetting xpSystemSetting = systemSettingMapper.selectOne(null); Integer operateFree = 0 ; if(null != xpSystemSetting) { operateFree = xpSystemSetting.getOperateFree(); } List<RouteOptionVo> options = new ArrayList<>(); for (Map.Entry<String, RouteVo> e : routeById.entrySet()) { String fid = e.getKey(); @@ -1065,6 +1072,7 @@ if (part.getFareEstimate() != null && part.getFareEstimate().getCouponId() == null) { opt.setCouponMessage("当前路线不满足优惠券使用条件"); } opt.setOperateFree(operateFree); options.add(opt); } @@ -1087,6 +1095,7 @@ XpTradingStrategyDetailVO strategyDetailVO = strategyDetailVOR.getData(); redisService.setCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + userId + ":" + snapshotId, JSON.toJSONString(payload), Long.valueOf(strategyDetailVO.getMaxStandingTiming()), TimeUnit.SECONDS); MultiRouteAndFareVo vo = new MultiRouteAndFareVo(); vo.setSnapshotId(snapshotId); vo.setGeneratedAtMillis(now); @@ -1095,6 +1104,8 @@ vo.setRoutePreferences(listRoutePreferences(routeAndFareDto.getOpenCityId(), userId)); vo.setStaleCheckSeconds(navigationStaleSeconds); vo.setPriceWaveThresholdPercent(navigationPriceWavePercent); vo.setOperateFree(operateFree); RouteOptionVo first = options.get(0); redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + userId, JSON.toJSONString(first.getRoute()), 24L, TimeUnit.HOURS); xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -22,6 +22,7 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.map.constant.I18nKeyConstant; import com.xiaopeng.map.service.*; import com.xiaopeng.map.service.serviceimpl.BootCommonService; import com.xiaopeng.map.utils.OperationStrategyIndex; import com.xiaopeng.api.query.operation.FenceAndStationVo; import io.swagger.annotations.Api; @@ -39,6 +40,7 @@ import javax.validation.constraints.NotNull; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -79,6 +81,8 @@ private XpPointService xpPointService; @Resource private XpStationService xpStationService; @Resource private BootCommonService bootCommonService; /** * 查询省市管理 @@ -201,6 +205,8 @@ ElectronicFenceDetailVo.Numbers stationNumbers = new ElectronicFenceDetailVo.Numbers(); if(CollUtil.isNotEmpty(stationList)){ LocalDateTime now = LocalDateTime.now(); LocalTime localTime = LocalTime.now(); //status 场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效 for (XpStation xpStation : stationList) { switch (xpStation.getStatus()) { @@ -212,41 +218,11 @@ break; case 2: //启动中 判断 待启动的状态 ,当前时间在 运营时间 内是启动中,否则是 待启动 LocalDateTime now = LocalDateTime.now(); if(xpStation.getOperationType() ==1){//运营类型 1=与运营区同步 2=自定义时间段 LocalDateTime startTime = electronicFence.getEffectTime();//生效时间 LocalDateTime endTime = electronicFence.getFailureTime();//失效时间 if(electronicFence.getFailureType() ==1) {// 失效类型 1=永不失效 2=定时失效 endTime = LocalDateTime.now().plusYears(1); } if(!now.isBefore(startTime) && !now.isAfter(endTime)){ stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); }else{ stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); } }else { //数据结构 [{"endTime": "18:00", "startTime": "05:00"}] JSONArray jsonArray = JSONObject.parseArray(xpStation.getEffectiveTimePeriod()); boolean flag = false; for (Object object : jsonArray) { JSONObject jsonObject = (JSONObject) object; String startTimeStr = jsonObject.getString("startTime"); String endTimeStr = jsonObject.getString("endTime"); startTimeStr = LocalDate.now() +" "+ startTimeStr+":00"; endTimeStr = LocalDate.now() + " " + endTimeStr + ":00"; LocalDateTime startTime = LocalDateTimeUtil.parse(startTimeStr, DatePattern.NORM_DATETIME_PATTERN); LocalDateTime endTime = LocalDateTimeUtil.parse(endTimeStr, DatePattern.NORM_DATETIME_PATTERN); if(!now.isBefore(startTime) && !now.isAfter(endTime)){ flag = true; } } if (flag){ stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); }else{ stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); } boolean stationOperation = bootCommonService.getStationOperation(localTime, xpStation.getOperationType(), xpStation.getEffectivePeriod(), xpStation.getEffectiveTimePeriod(), xpStation.getFenceOperationStrategy()); if (stationOperation) { stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); }else{ stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); } break; case 3: xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointController.java
@@ -1,8 +1,11 @@ package com.xiaopeng.map.controller; import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.map.dto.NearestDto; import com.xiaopeng.map.dto.StationDetailQueryDto; import com.xiaopeng.map.service.XpPointService; import com.xiaopeng.map.vo.NearestVo; import com.xiaopeng.map.vo.StationDetailVo; import com.xiaopeng.unifiedverification.interceptor.XpClientCheck; import io.swagger.annotations.Api; @@ -16,6 +19,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; @Slf4j @RestController @@ -37,4 +41,6 @@ String uid = request.getHeader("XP-Uid"); return R.ok(xpPointService.queryStationDetail(dto, uid)); } } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpStationManagementController.java
@@ -3,6 +3,7 @@ import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpStation; import com.xiaopeng.api.query.operation.XpStationQuery; import com.xiaopeng.api.vo.account.LoginUser; @@ -13,6 +14,7 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.security.service.TokenService; import com.xiaopeng.map.exportExcel.XpStationExportExcel; import com.xiaopeng.map.service.XpElectronicFenceService; import com.xiaopeng.map.service.XpPointService; import com.xiaopeng.map.service.XpStationService; import io.swagger.annotations.Api; @@ -50,12 +52,13 @@ private TokenService tokenService; @Resource private XpPointService xpPointService; @Resource private XpElectronicFenceService xpElectronicFenceService; @ApiOperation(value = "场站管理已经启动列表", tags = {"管理后台-运营-场站管理"}) @GetMapping("/findListEnable") public R<List<XpStation>> findListByCityCode(@RequestParam String cityCode) { XpStationQuery query = new XpStationQuery(); query.setCityCode(cityCode); return R.ok( xpStationService.findList(query)); @@ -86,6 +89,14 @@ XpStationVo beanVo = new XpStationVo(); BeanUtils.copyProperties(bean, beanVo); beanVo.setXpPointList(xpPointService.listByStationId(bean.getId())); XpElectronicFence electronicFence = xpElectronicFenceService.getById(bean.getElectronicId()); beanVo.setFenceEffectType(electronicFence.getEffectType()); beanVo.setFenceEffectTime(electronicFence.getEffectTime()); beanVo.setFenceFailureType(electronicFence.getFailureType()); beanVo.setFenceFailureTime(electronicFence.getFailureTime()); return R.ok(beanVo); } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NearestDto.java
@@ -10,12 +10,13 @@ @ApiModel(value = "NearestDto", description = "附近上车站点") public class NearestDto { @ApiModelProperty(value = "经度") @NotNull(message = "经度不能为空") private Double longitude; @ApiModelProperty(value = "纬度") @NotNull(message = "纬度不能为空") private Double latitude; @ApiModelProperty(value = "经度") @NotNull(message = "经度不能为空") private Double longitude; } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/StationDetailQueryDto.java
@@ -1,5 +1,7 @@ package com.xiaopeng.map.dto; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -12,6 +14,7 @@ @ApiModelProperty(value = "场站id") @NotNull(message = "场站id不能为空") @JsonSerialize(using = ToStringSerializer.class) private Long stationId; @ApiModelProperty(value = "当前纬度") xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java
@@ -36,6 +36,9 @@ List<XpPoint> pageList(@Param("pageInfo") PageInfo<XpPoint> pageInfo, @Param("query") PointPageListListQuery query); List<XpPoint> pageList( @Param("query") PointPageListListQuery query); @Select("SELECT point_number FROM xp_point WHERE point_number LIKE CONCAT(#{cityPrefix}, '-', #{bizType}, '-%') ORDER BY point_number DESC LIMIT 1") String selectMaxPointNumber(@Param("cityPrefix") String cityPrefix, @Param("bizType") String bizType); } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java
@@ -66,12 +66,6 @@ StationDetailVo queryStationDetail(@Valid StationDetailQueryDto dto, String uid); /** * 判断点位是否时间段内 * @param now * @return */ boolean getInTime(LocalTime now, Integer effectivePeriod, String effectiveTimePeriod); List<XpPoint> pointMap(PointMapQuery query); List<FenceAndStationVo> findListFenceAndStation(String cityCode); @@ -112,6 +106,8 @@ OrderDistanceVo getOrderDistance(); List<XpPoint> pageList(PageInfo<XpPoint> pageInfo, PointPageListListQuery query); PageInfo<XpPoint> pageList(PointPageListListQuery query); Set<Long> getCollectStationIds(String uid); @@ -129,4 +125,7 @@ @Transactional(rollbackFor = Exception.class) void pointDeleteByStationId(Long stationId, Boolean pointDelete); void setStatusFailure(List<Long> electronicAreaIds); } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpStationService.java
@@ -22,8 +22,11 @@ */ public interface XpStationService extends IService<XpStation> { List<XpStation> findList(XpStationQuery query); List<XpStation> findList(PageInfo<XpStation> pageInfo, XpStationQuery query); PageInfo<XpStation> pageList(XpStationQuery query); void validate(XpStationVo dto); xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/BootCommonService.java
New file @@ -0,0 +1,206 @@ package com.xiaopeng.map.service.serviceimpl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.api.vo.order.XpPointsListVo; import com.xiaopeng.common.core.utils.DateUtils; import com.xiaopeng.map.service.XpStationService; import com.xiaopeng.map.utils.TimeRangeChecker; import com.xiaopeng.map.utils.holiday.HolidayUtil; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalTime; @Service public class BootCommonService { @Resource private HolidayUtil holidayUtil; // /** * 判断围栏运营策略 * 自定义时 选择每天只能有一个运营策略 * type = 0工作日 1法定节假日 2非工作日 3自定义时间 typeStr 代表周 = [1,2,3,4,5,6,7] typeStr= 0的时候代表每天 * [{"name": "策略组1", "time": ["09:00-18:00"], "type": 0, "typeStr": []}, * {"name": "策略组2", "time": ["08:00-21:00"], "type": 2, "typeStr": []}, * {"name": "策略组3", "time": ["07:00-22:00"], "type": 1, "typeStr": []}, * {"name": "策略组4", "time": ["12:00-19:00"], "type": 3, "typeStr": [1, 3, 5, 7]}] * * [{"name": "策略组1", "time": ["08:00-22:00"], "type": 3, "typeStr": [0]}] * @param electronicOperationStrategy * @return * */ public Boolean getFenceOperation(String electronicOperationStrategy) { return getFenceOperation(LocalTime.now(),electronicOperationStrategy); } public Boolean getFenceOperation(LocalTime localTime,String electronicOperationStrategy) { if(StrUtil.isBlank(electronicOperationStrategy)){ return true; } JSONArray jsonArray = JSONArray.parseArray(electronicOperationStrategy); Integer holidayToday = holidayUtil.isHolidayToday(); //0工作日 1节假日 2非工作日 for (Object o : jsonArray) { JSONObject jsonObject =JSONObject.parseObject(o.toString()); String type = jsonObject.getString("type"); String timeStr = null; if(type.equals(holidayToday.toString())){ timeStr = jsonObject.getString("time"); }else if("3".equals(type)){ // 判断是什么类型 0每天 1-7 想起 String typeStr = jsonObject.getString("typeStr"); // 查看今天周几 Integer week = DateUtils.getWeek(); // 包含每天 或者 包含当天 if(typeStr.contains("0") || typeStr.contains(week.toString())){ timeStr = jsonObject.getString("time"); } } if(StrUtil.isNotBlank(timeStr)){ JSONArray time = jsonObject.getJSONArray("time"); // 判断当前时间 是否在time时间段中 for (Object object : time) { String[] timeArray = object.toString().split("-"); String startTime = timeArray[0]; String endTime = timeArray[1]; boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(localTime,startTime, endTime); if(currentTimeInRange){ return true; } } } } return false; } /** * 判断场站运营策略 * ["06:00-12:00", "13:00-21:00"] * @param localTime * @param operationType 运营类型 1=与运营区同步 2=自定义时间段 * @param effectivePeriod 生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日 * @param effectiveTimePeriod 场站生效时间段 json * @param effectiveTimePeriod 围栏运营json * @return */ public boolean getStationOperation(LocalTime localTime,Integer operationType,Integer effectivePeriod, String effectiveTimePeriod,String fenceOperationStrategy){ if(operationType == 1){ return getFenceOperation(localTime,fenceOperationStrategy); }else { Integer holidayToday = holidayUtil.isHolidayToday(); if (effectivePeriod == 1) { boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 2) { if (holidayToday != 0) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 3) { if (holidayToday != 2) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 4) { if (holidayToday != 1) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } } return true; } /** * * @param localTime 时间 * @param xpPoint 点位对象 * @return */ public boolean getPointOperation(LocalTime localTime, XpPoint xpPoint){ if(xpPoint.getOperationType()==2){//运营类型 1=与运营区同步 2=自定义时间段 return getPointOperation(localTime,xpPoint.getEffectivePeriod(),xpPoint.getEffectiveTimePeriod()); }else { if(xpPoint.getStationId()==null){//调用围栏运营策略 return getFenceOperation(localTime,xpPoint.getFenceOperationStrategy()); }else { return this.getStationOperation(localTime,xpPoint.getStationOperationType(),xpPoint.getStationEffectivePeriod(),xpPoint.getStationEffectiveTimePeriod(),xpPoint.getFenceOperationStrategy()); } } } public boolean getPointOperation_vo(LocalTime localTime, XpPointsListVo xpPoint){ if(xpPoint.getOperationType()==2){//运营类型 1=与运营区同步 2=自定义时间段 return getPointOperation(localTime,xpPoint.getEffectivePeriod(),xpPoint.getEffectiveTimePeriod()); }else { if(xpPoint.getStationId()==null){//调用围栏运营策略 return getFenceOperation(localTime,xpPoint.getFenceOperationStrategy()); }else { return this.getStationOperation(localTime,xpPoint.getStationOperationType(),xpPoint.getStationEffectivePeriod(),xpPoint.getStationEffectiveTimePeriod(),xpPoint.getFenceOperationStrategy()); } } } /** * 判断点位是否运营策略 * ["06:00-12:00", "13:00-21:00"] * @param localTime * @param effectivePeriod 生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日 * @param effectiveTimePeriod 场站运营json/ 生效时间段 json * @return */ private boolean getPointOperation(LocalTime localTime, Integer effectivePeriod, String effectiveTimePeriod){ // 2非工作日 0工作日 1节假日 3调休日 Integer holidayToday = holidayUtil.isHolidayToday(); if (effectivePeriod == 1) { boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 2) { if (holidayToday != 0) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 3) { if (holidayToday != 2) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } else if (effectivePeriod == 4) { if (holidayToday != 1) { return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod); if (!inTime) { return false; } } return true; } } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java
@@ -36,6 +36,7 @@ import com.xiaopeng.map.vo.WalkTimeVo; import io.swagger.annotations.ApiModelProperty; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.data.geo.Point; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; @@ -86,6 +87,9 @@ private GDMapGeocodingUtil gdMapGeocodingUtil; @Autowired private XpPointService xpPointService; @Lazy @Autowired private BootCommonService bootCommonService; @@ -126,7 +130,7 @@ if(xpElectronicFence.getFailureType() == 2){ JSONArray jsonArray = JSONArray.parseArray(operationStrategy); if(!jsonArray.isEmpty()){ Boolean inOperationTime = isInOperationTime(operationStrategy); Boolean inOperationTime = bootCommonService.getFenceOperation(operationStrategy); if(!inOperationTime){ continue; } @@ -180,53 +184,7 @@ } /** * 是否在运营内 * @param operationStrategy 规则json字符串 * @return */ private Boolean isInOperationTime(String operationStrategy) { JSONArray jsonArray = JSONArray.parseArray(operationStrategy); Integer holidayToday = holidayUtil.isHolidayToday(); for (Object o : jsonArray) { JSONObject jsonObject =JSONObject.parseObject(o.toString()); String type = jsonObject.getString("type"); if(type.equals(holidayToday.toString())){ JSONArray time = jsonObject.getJSONArray("time"); // 判断当前时间 是否在time时间段中 for (Object object : time) { String[] timeArray = object.toString().split("-"); String startTime = timeArray[0]; String endTime = timeArray[1]; boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime); if(currentTimeInRange){ return true; } } }else if(type.equals("3")){ // 判断是什么类型 0每天 1-7 想起 String typeStr = jsonObject.getString("typeStr"); // 查看今天周几 Integer week = DateUtils.getWeek(); // 包含每天 或者 包含当天 if(typeStr.contains("0") || typeStr.contains(week.toString())){ JSONArray time = jsonObject.getJSONArray("time"); // 判断当前时间 是否在time时间段中 for (Object object : time) { String[] timeArray = object.toString().split("-"); String startTime = timeArray[0]; String endTime = timeArray[1]; boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime); if(currentTimeInRange){ return true; } } } } } return false; } @@ -260,7 +218,7 @@ String operationStrategy = electronicFence.getOperationStrategy(); Boolean inOperationTime = true; if(electronicFence.getFailureType() == 2){ inOperationTime = isInOperationTime(operationStrategy); inOperationTime = bootCommonService.getFenceOperation(operationStrategy); } XpElectronicFenceArea electronicFenceArea = this.getById(Long.valueOf(polygon.getAreaId())); if(inOperationTime && null != electronicFenceArea && !electronicFenceArea.getDeleted()){ xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -12,6 +12,8 @@ import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon; import com.xiaopeng.api.model.operation.*; import com.xiaopeng.api.query.operation.ElectronicPageListQuery; 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.exception.ServiceException; import com.xiaopeng.common.core.utils.DateUtils; @@ -56,6 +58,7 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @@ -77,6 +80,9 @@ private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper; @Autowired private MongoTemplate mongoTemplate; @Lazy @Resource private BootCommonService bootCommonService; @Autowired private XpPointMapper xpPointMapper; @@ -98,6 +104,8 @@ @Lazy protected XpStationService xpStationService; @Override public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) { if (query == null) { @@ -111,6 +119,7 @@ if (total == 0L) { return new PageInfo<>(); } LocalTime localTime = LocalTime.now(); List<XpElectronicFence> list = this.baseMapper.pageList(pageInfo, query); List<Long> electronicIds = list.stream().map(XpElectronicFence::getId).collect(Collectors.toList()); Map<Long, List<XpElectronicFenceArea>> electronicFenceAreaMap = xpElectronicFenceAreaMapper.selectList(new LambdaQueryWrapper<XpElectronicFenceArea>() @@ -118,13 +127,34 @@ .collect(Collectors.groupingBy(XpElectronicFenceArea::getElectronicId)); for (XpElectronicFence xpElectronicFence : list) { List<XpElectronicFenceArea> xpElectronicFenceAreas = electronicFenceAreaMap.get(xpElectronicFence.getId()); xpElectronicFence.setOperatingAreaCount(0L); xpElectronicFence.setProhibitedAreaCount(0L); xpElectronicFence.setFenceAreaPointCount(0l); 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); } try { PointPageListListQuery queryPoint = new PointPageListListQuery(); queryPoint.setElectronicId(xpElectronicFence.getId()); List<XpPoint> xpPoints = xpPointMapper.pageList( queryPoint); if(CollUtil.isNotEmpty(xpPoints)){ Long fenceAreaPointCount = 0L; for (XpPoint xpPoint : xpPoints) { boolean intime = bootCommonService.getPointOperation(localTime, xpPoint); if(intime){ fenceAreaPointCount++; } } xpElectronicFence.setFenceAreaPointCount(fenceAreaPointCount); } } catch (Exception e) { e.printStackTrace(); throw new ServiceException("查询错误"); } } pageInfo.setRecords(list); return pageInfo; @@ -1056,16 +1086,18 @@ List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery() .eq(XpElectronicFenceArea::getElectronicId, electronicId) .list(); List<Long> electronicAreaIds = new ArrayList<>(); if (!CollUtil.isEmpty(electronicFenceAreaList)) { for (XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList) { electronicFenceArea.setAreaStatus(2); toDeleteAreaIdStrings.add(String.valueOf(electronicFenceArea.getId())); electronicAreaIds.add(electronicFenceArea.getId()); } xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList); } //点位失效 xpPointService.setStatusFailure(electronicAreaIds); //场站失效 xpStationService.setStatusFailure(electronicId);//场站失效 // 删除旧的区域数据,然后保存新的区域数据 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
@@ -12,15 +12,12 @@ import com.xiaopeng.api.dto.order.HistoryEndPointsDto; import com.xiaopeng.api.dto.order.HistoryStartPointsDto; import com.xiaopeng.api.feignClient.account.XpAppUserCollectAddrClient; import com.xiaopeng.api.model.operation.XpElectronicFenceArea; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.api.model.operation.XpRegion; import com.xiaopeng.api.model.operation.XpStation; import com.xiaopeng.api.model.operation.XpSystemSetting; import com.xiaopeng.api.model.operation.*; import com.xiaopeng.api.query.operation.FenceAndStationVo; import com.xiaopeng.api.query.operation.PointListQuery; import com.xiaopeng.api.query.operation.PointPageListListQuery; import com.xiaopeng.api.query.operation.XpStationQuery; import com.xiaopeng.api.vo.account.LoginUser; import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo; import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo; import com.xiaopeng.api.vo.order.XpPointsListVo; @@ -31,19 +28,19 @@ import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.common.security.service.TokenService; import com.xiaopeng.evi.oss.service.AliOssService; import com.xiaopeng.map.constant.I18nKeyConstant; import com.xiaopeng.map.dto.NearestDto; import com.xiaopeng.map.dto.StationDetailQueryDto; import com.xiaopeng.map.mapper.XpPointMapper; import com.xiaopeng.map.mapper.XpElectronicFenceMapper; import com.xiaopeng.map.mapper.XpPointMapper; import com.xiaopeng.map.mapper.XpRegionMapper; import com.xiaopeng.map.mapper.XpSystemSettingMapper; import com.xiaopeng.map.query.PointByNameQuery; import com.xiaopeng.map.service.XpElectronicFenceAreaService; import com.xiaopeng.map.service.XpPointService; import com.xiaopeng.map.service.XpStationService; import com.xiaopeng.map.utils.TimeRangeChecker; import com.xiaopeng.map.utils.holiday.HolidayUtil; import com.xiaopeng.map.utils.map.map.FastDistanceCalculator; import com.xiaopeng.map.vo.*; @@ -116,6 +113,9 @@ @Autowired private AliOssService aliOssService; @Lazy @Autowired private BootCommonService bootCommonService; @Override @Transactional @@ -228,10 +228,18 @@ orderDistance = xpSystemSetting.getNearPointDistance(); } // 获取所有的站点信息 List<XpPoint> list = list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getOperationStatus, 2).eq(XpPoint::getPointType,1).isNotNull(XpPoint::getElectronicAreaId) // 添加距离计算字段 .apply("ST_Distance_Sphere(point({0}, {1}), point(point_lon, point_lat)) <= {2}", dto.getLongitude(), dto.getLatitude(), orderDistance)); PointPageListListQuery query = new PointPageListListQuery(); query.setOperationStatus(2); query.setPointType(1); query.setElectronicAreaIdNotNull(true); query.setLongitude(dto.getLongitude()); query.setLatitude(dto.getLatitude()); query.setOrderDistance(orderDistance); List<XpPoint> list = baseMapper.pageList(query); // 添加距离计算字段 // List<XpPoint> list = list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getOperationStatus, 2).eq(XpPoint::getPointType,1).isNotNull(XpPoint::getElectronicAreaId) // .apply("ST_Distance_Sphere(point({0}, {1}), point(point_lon, point_lat)) <= {2}", // dto.getLongitude(), dto.getLatitude(), orderDistance)); NearestVo nearestVo = new NearestVo(); List<NearestNextVo> nearestNextVos = new ArrayList<>(); LocalTime now = LocalTime.now(); @@ -239,7 +247,7 @@ for (XpPoint xpPoint : list) { // 判断是否在时间段内 boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod()); boolean intime = bootCommonService.getPointOperation(now, xpPoint); if (!intime) { continue; } @@ -325,42 +333,6 @@ } public boolean getInTime(LocalTime now, Integer effectivePeriod, String effectiveTimePeriod){ // 2非工作日 0工作日 1节假日 3调休日 Integer holidayToday = holidayUtil.isHolidayToday(); if(effectivePeriod==1){ boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod); if (!inTime) { return false; } }else if(effectivePeriod==2){ if(holidayToday!=0){ return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod); if (!inTime) { return false; } }else if(effectivePeriod==3){ if(holidayToday!=2){ return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod); if (!inTime) { return false; } }else if(effectivePeriod==4){ if(holidayToday!=1){ return false; } boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod); if (!inTime) { return false; } } return true; } @Override public List<XpPoint> pointMap(PointMapQuery query) { @@ -462,37 +434,47 @@ return stationDetailVo; } XpStation station = xpStationService.getById(dto.getStationId()); if (station == null || !isStationAvailable(station)) { XpStationQuery query = new XpStationQuery(); query.setId(dto.getStationId()); query.setStatus(2); List<XpStation> list = xpStationService.findList(query); if(CollUtil.isEmpty(list)){ return stationDetailVo; } XpStation station = list.get(0); LocalTime localTime = LocalTime.now(); boolean stationOperation = bootCommonService.getStationOperation(localTime, station.getOperationType(), station.getEffectivePeriod(), station.getEffectiveTimePeriod(), station.getFenceOperationStrategy()); if(!stationOperation){ return stationDetailVo; } // 仅查询场站下运营点位,最终结果还会叠加时段/围栏有效性过滤。 List<XpPoint> stationPoints = this.lambdaQuery() .eq(XpPoint::getStationId, station.getId()) .eq(XpPoint::getPointType, 1) .eq(XpPoint::getOperationStatus, 2) .list(); PointPageListListQuery queryPoint = new PointPageListListQuery(); queryPoint.setStationId( station.getId()); queryPoint.setPointType(1); queryPoint.setOperationStatus(2); List<XpPoint> stationPoints = this.baseMapper.pageList(queryPoint); if (CollUtil.isEmpty(stationPoints)) { return stationDetailVo; } Map<Long, XpElectronicFenceArea> areaMap = buildAreaMap(stationPoints.stream() .map(XpPoint::getElectronicAreaId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList())); Map<Long, XpElectronicFence> fenceMap = buildFenceMap(areaMap.values().stream() .map(XpElectronicFenceArea::getElectronicId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList())); // Map<Long, XpElectronicFenceArea> areaMap = buildAreaMap(stationPoints.stream() // .map(XpPoint::getElectronicAreaId) // .filter(Objects::nonNull) // .distinct() // .collect(Collectors.toList())); // Map<Long, XpElectronicFence> fenceMap = buildFenceMap(areaMap.values().stream() // .map(XpElectronicFenceArea::getElectronicId) // .filter(Objects::nonNull) // .distinct() // .collect(Collectors.toList())); Set<Long> collectStationIds = getCollectStationIds(uid); Set<Long> collectPointIds = getCollectPointIds(uid); // 默认点位优先置顶,其余点位再按场站内排序和距离排序。 List<StationPointItemVo> points = stationPoints.stream() .filter(point -> isPointAvailable(point, areaMap, fenceMap)) .filter(point -> isPointAvailable(localTime, point)) .map(point -> toStationPointItem(point, station.getDefaultPointId(), dto.getLatitude(), dto.getLongitude(), collectPointIds)) .sorted(buildStationPointComparator()) .collect(Collectors.toList()); @@ -519,10 +501,10 @@ if (list.isEmpty()) { return searchVo; } LocalTime now = LocalTime.now(); for (XpPointsListVo xpPointsListVo : list) { boolean inTime = getInTime(now, xpPointsListVo.getEffectivePeriod(), xpPointsListVo.getEffectiveTimePeriod()); boolean inTime = bootCommonService.getPointOperation_vo(now, xpPointsListVo); if (!inTime) { // 不在运营段 xpPointsListVo.setState(0); @@ -557,35 +539,16 @@ return orderDistanceVo; } @Override public PageInfo<XpPoint> pageList(PointPageListListQuery query) { if(CollUtil.isNotEmpty(query.getFenceAndStationList())){ List<String> fenceAreaIds = new ArrayList<>(); List<String> stationIds = new ArrayList<>(); for (FenceAndStationVo bean : query.getFenceAndStationList()) { if(bean.getType()==1){ fenceAreaIds.addAll(StrUtil.split(bean.getIds(),",") ); }else{ stationIds.addAll(StrUtil.split(bean.getIds(),",") ); } } query.setFenceAreaIds(fenceAreaIds); query.setStationIds(stationIds); public List<XpPoint> pageList(PageInfo<XpPoint> pageInfo, PointPageListListQuery query) { List<XpPoint> list = null; if (pageInfo == null) { list = this.baseMapper.pageList(query); }else{ list = this.baseMapper.pageList(pageInfo,query); } PageInfo<XpPoint> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize()); if (StringUtils.isNotBlank(query.getPointLonAndLat())) { List<String> lonAndLat = query.getPointLonAndLat().trim().contains(",") ? Arrays.asList(query.getPointLonAndLat().split(",")) : query.getPointLonAndLat().trim().contains(" ") ? Arrays.asList(query.getPointLonAndLat().split(" ")) : Collections.emptyList(); if (CollUtil.isNotEmpty(lonAndLat)) { query.setPointLon(lonAndLat.get(0)); query.setPointLat(lonAndLat.get(1)); query.setPointLonAndLat(null); } } List<XpPoint> list = this.baseMapper.pageList(pageInfo,query); if(CollUtil.isNotEmpty(list)){ /** * hover在状态标签时,展示信息 @@ -603,11 +566,11 @@ } if(point.getVerificationStatus()==5 && point.getOperationStatus() == 1){ if(point.getOperationType() == 1){//运营类型 1=与运营区同步 2=自定义时间段 ; ; //[{"name": "策略组1", "time": ["06:00-12:00", "13:00-22:59"], "type": 0, "typeStr": []}, // {"name": "策略组2", "time": ["05:00-12:00", "12:00-16:00"], "type": 2, "typeStr": ""}, // {"name": "策略组3", "time": ["09:00-21:59"], "type": 1, "typeStr": ""}] JSONArray electronicOperationStrategys = JSONArray.parseArray(point.getElectronicOperationStrategy()); JSONArray electronicOperationStrategys = JSONArray.parseArray(point.getFenceOperationStrategy()); if(!electronicOperationStrategys.isEmpty()){ StringJoiner joiner = new StringJoiner(";"); for (Object electronicOperationStrategy : electronicOperationStrategys) { @@ -622,13 +585,43 @@ if(StrUtil.isNotBlank(point.getEffectiveTimePeriod()) ){ List<String> effectiveTimePeriods = JSONArray.parseArray(point.getEffectiveTimePeriod(), String.class); hoverStatusDes = String.join(";", effectiveTimePeriods); // hoverStatusDes = "待生效:"+point.getElectronicEffectTime().toString() ; } } } point.setHoverStatusDes(hoverStatusDes); } } return list; } @Override public PageInfo<XpPoint> pageList(PointPageListListQuery query) { if(CollUtil.isNotEmpty(query.getFenceAndStationList())){ List<String> fenceAreaIds = new ArrayList<>(); List<String> stationIds = new ArrayList<>(); for (FenceAndStationVo bean : query.getFenceAndStationList()) { if(bean.getType()==1){ fenceAreaIds.addAll(StrUtil.split(bean.getIds(),",") ); }else{ stationIds.addAll(StrUtil.split(bean.getIds(),",") ); } } query.setFenceAreaIds(fenceAreaIds); query.setStationIds(stationIds); } PageInfo<XpPoint> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize()); if (StringUtils.isNotBlank(query.getPointLonAndLat())) { List<String> lonAndLat = query.getPointLonAndLat().trim().contains(",") ? Arrays.asList(query.getPointLonAndLat().split(",")) : query.getPointLonAndLat().trim().contains(" ") ? Arrays.asList(query.getPointLonAndLat().split(" ")) : Collections.emptyList(); if (CollUtil.isNotEmpty(lonAndLat)) { query.setPointLon(lonAndLat.get(0)); query.setPointLat(lonAndLat.get(1)); query.setPointLonAndLat(null); } } List<XpPoint> list = this.pageList(pageInfo,query); pageInfo.setRecords(list); return pageInfo; } @@ -652,75 +645,19 @@ .collect(Collectors.toMap(XpElectronicFence::getId, fence -> fence, (a, b) -> a)); } /** * 场站可展示判断: * 1. 状态必须为启用中; * 2. 与运营区同步时,依赖运营区和围栏的当前有效性; * 3. 自定义时段时,依赖场站自身时段配置。 */ private boolean isStationAvailable(XpStation station) { if (station == null || !Integer.valueOf(6).equals(station.getStatus())) { return false; } if (Integer.valueOf(1).equals(station.getOperationType())) { if (station.getElectronicAreaId() == null) { return false; } XpElectronicFenceArea area = xpElectronicFenceAreaService.getById(station.getElectronicAreaId()); if (area == null || !Integer.valueOf(1).equals(area.getAreaStatus()) || area.getElectronicId() == null) { return false; } XpElectronicFence fence = xpElectronicFenceMapper.selectById(area.getElectronicId()); return isFenceAvailable(fence); } if (Integer.valueOf(2).equals(station.getOperationType()) && station.getEffectivePeriod() != null && StringUtils.isNotBlank(station.getEffectiveTimePeriod())) { return getInTime(LocalTime.now(), station.getEffectivePeriod(), station.getEffectiveTimePeriod()); } return false; } /** * 子点位是否可展示与场站卡片中。 * 规则与现有点位有效性保持一致,避免地图页和其他点位查询出现口径偏差。 */ private boolean isPointAvailable(XpPoint point, Map<Long, XpElectronicFenceArea> areaMap, Map<Long, XpElectronicFence> fenceMap) { if (point == null || !Integer.valueOf(2).equals(point.getOperationStatus())) { return false; } if (Integer.valueOf(1).equals(point.getOperationType())) { if (point.getElectronicAreaId() == null) { return false; } XpElectronicFenceArea area = areaMap.get(point.getElectronicAreaId()); if (area == null || !Integer.valueOf(1).equals(area.getAreaStatus()) || area.getElectronicId() == null) { return false; } return isFenceAvailable(fenceMap.get(area.getElectronicId())); } if (Integer.valueOf(2).equals(point.getOperationType()) && point.getEffectivePeriod() != null && StringUtils.isNotBlank(point.getEffectiveTimePeriod())) { return getInTime(LocalTime.now(), point.getEffectivePeriod(), point.getEffectiveTimePeriod()); } return false; private boolean isPointAvailable(LocalTime localTime, XpPoint point) { return bootCommonService.getPointOperation(localTime, point); } /** * 围栏生效判断: * 启用中,且当前时间需要落在生效时间与失效时间窗口内。 */ private boolean isFenceAvailable(XpElectronicFence fence) { if (fence == null || !Integer.valueOf(2).equals(fence.getStatus())) { return false; } LocalDateTime now = LocalDateTime.now(); if (fence.getEffectTime() != null && now.isBefore(fence.getEffectTime())) { return false; } return !Integer.valueOf(2).equals(fence.getFailureType()) || fence.getFailureTime() == null || !now.isAfter(fence.getFailureTime()); } /** * 组装单个场站子点位返回对象,并在有默认点位配置时打标。 @@ -881,4 +818,32 @@ } } @Resource private TokenService tokenService; /** * 场站 失效-围栏失效 场站失效 * @param electronicAreaIds */ @Override public void setStatusFailure(List<Long> electronicAreaIds){ if(CollUtil.isNotEmpty(electronicAreaIds)){ LambdaQueryWrapper<XpPoint> query = new LambdaQueryWrapper<>(); query.in(XpPoint::getElectronicAreaId, electronicAreaIds); query.eq(XpPoint::getDeleted, 0); List<XpPoint> list = super.list(query); if(!list.isEmpty()){ LoginUser loginUser = tokenService.getLoginUser(); for (XpPoint bean : list) { bean.setUpdateBy(loginUser.getUsername()); bean.setUpdateTime(LocalDateTime.now()); bean.setOperationStatus(4);//场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效 boolean b = updateById(bean); } } } } } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpStationServiceImpl.java
@@ -1,11 +1,12 @@ package com.xiaopeng.map.service.serviceimpl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.model.map.XpGeoFencingPolygon; import com.xiaopeng.api.model.operation.*; import com.xiaopeng.api.query.operation.PointListQuery; import com.xiaopeng.api.query.operation.PointPageListListQuery; import com.xiaopeng.api.query.operation.XpStationQuery; import com.xiaopeng.api.vo.account.LoginUser; import com.xiaopeng.api.vo.operation.XpStationVo; @@ -36,8 +37,11 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * <p> @@ -58,6 +62,7 @@ private MongoTemplate mongoTemplate; @Resource private PolygonOverlapService polygonOverlapService; @Lazy @Resource private XpElectronicFenceService xpElectronicFenceService; @Resource @@ -69,10 +74,58 @@ @Lazy @Resource private XpPointService xpPointService; @Lazy @Resource private BootCommonService bootCommonService; @Override public List<XpStation> findList(XpStationQuery query) { return this.baseMapper.pageList( query); return this.findList(null, query); } @Override public List<XpStation> findList(PageInfo<XpStation> pageInfo, XpStationQuery query) { List<XpStation> list = null; if(pageInfo ==null){ list = this.baseMapper.pageList(query); }else{ list = this.baseMapper.pageList(pageInfo, query); } if(CollUtil.isNotEmpty(list)){ LocalTime localTime = LocalTime.now(); List<String> stationIds = new ArrayList<>(); for (XpStation xpStation : list) { stationIds.add(xpStation.getId().toString()); } PointPageListListQuery queryPoint = new PointPageListListQuery(); queryPoint.setStationIds(stationIds); List<XpPoint> xpPoints = xpPointService.pageList(null, queryPoint); // 将点位按场站ID分组,提高后续处理效率 Map<Long, List<XpPoint>> pointMap = xpPoints.stream() .collect(Collectors.groupingBy(XpPoint::getStationId)); for (XpStation xpStation : list) { xpStation.setPointCount(0); xpStation.setOperatingPointCount(0); List<XpPoint> stationPoints = pointMap.get(xpStation.getId()); if (CollUtil.isNotEmpty(stationPoints)) { xpStation.setPointCount(stationPoints.size()); int operatingPointCount = 0; // 运营中点位数 for (XpPoint xpPoint : stationPoints) { boolean pointOperation = bootCommonService.getPointOperation(localTime, xpPoint); if (pointOperation) { operatingPointCount++; } } xpStation.setOperatingPointCount(operatingPointCount); } } } return list; } @Override @@ -81,18 +134,10 @@ if (null == query.getCreateSort() && null == query.getUpdateSort()){ query.setCreateSort(2); } List<XpStation> list = this.baseMapper.pageList(pageInfo, query); if (list.isEmpty()) { List<XpStation> list = this.findList(pageInfo, query); if(CollUtil.isEmpty(list)){ return new PageInfo<>(); } for (XpStation xpStation : list) { xpStation.setPointCount(0); xpStation.setOperatingPointCount(0); List<XpPoint> xpPoints = xpPointService.listByStationId((xpStation.getId())); if(CollUtil.isNotEmpty(xpPoints)){ xpStation.setPointCount(xpPoints.size()); xpStation.setOperatingPointCount((int) xpPoints.stream().filter(p -> p.getOperationStatus() != null && p.getOperationStatus() == 2).count()); } } pageInfo.setRecords(list); return pageInfo; xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/holiday/HolidayUtil.java
@@ -48,7 +48,7 @@ } /** * 2非工作日 0工作日 1节假日 3调休日 * 2非工作日 0工作日 1节假日 * @return */ public Integer isHolidayToday() { xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml
@@ -137,9 +137,15 @@ <select id="queryPointByName" resultType="com.xiaopeng.api.vo.order.XpPointsListVo"> select p.id,p.electronic_area_id as electronicAreaId,p.point_name as name,p.point_address as address, p.point_lon as longitude,p.point_lat as latitude,p.effective_period,p.effective_time_period,p.point_on_off, from xp_electronic_fence_area xefa left join xp_point p on p.electronic_area_id = xefa.id p.point_lon as longitude,p.point_lat as latitude, p.operation_type,p.effective_period,p.effective_time_period,p.point_on_off,p.station_id, xef.operation_strategy fenceOperationStrategy, xs.station_name as stationName, xs.operation_type as stationOperationType, xs.effective_period xs.effective_time_period as stationEffectiveTimePeriod from xp_point p inner join xp_electronic_fence_area xefa on p.electronic_area_id = xefa.id inner join xp_electronic_fence xef on xef.id = xefa.electronic_id left join xp_station xs on xs.id = xp.station_id where p.is_deleted = 0 and p.operation_status =2 and xefa.is_deleted = 0 and xefa.area_status = 1 and p.electronic_area_id is not null and xefa.city_code = #{query.cityCode} @@ -151,14 +157,12 @@ </if> </select> <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpPoint"> select xp.id,xp.point_number as pointNumber,xp.point_name as pointName,xp.point_poi as pointPoi, xp.point_address as pointAddress,xp.city_code,xp.point_on_off,xp.operation_type,xp.effective_time_period, xp.point_lon as pointLon,xp.point_lat as pointLat,xp.create_time as createTime,xp.create_by as createBy ,xp.parking_time_limit as parkingTimeLimit,xp.verification_status as verificationStatus,xp.operation_status as operationStatus ,xp.station_id as stationId,xp.station_sort_no as stationSortNo,xp.remarks, xef.electronic_name as electronicName,xs.station_name as stationName,xef.effect_time, xef.operation_strategy electronicOperationStrategy select xp.*, xef.electronic_name as electronicName, xef.effect_time, xef.operation_strategy fenceOperationStrategy, xs.station_name as stationName, xs.operation_type as stationOperationType, xs.effective_period as stationEffectivePeriod, xs.effective_time_period as stationEffectiveTimePeriod from xp_point xp left join xp_electronic_fence_area xefa on xefa.id = xp.electronic_area_id left join xp_electronic_fence xef on xef.id = xefa.electronic_id @@ -185,9 +189,31 @@ ) </if> <if test="query.electronicId != null "> and xef.id = #{query.electronicId} </if> <if test="query.stationId != null "> and xp.station_id = #{query.stationId} </if> <if test="query.cityCode != null and query.cityCode != ''"> and xp.city_code = #{query.cityCode} </if> <if test="query.pointType != null"> and xp.point_type = #{query.pointType} </if> <if test="query.operationStatus != null"> and xp.operation_status = #{query.operationStatus} </if> <if test="query.electronicAreaIdNotNull != null"> and xp.electronic_area_id is not null </if> <if test="query.orderDistance != null"> and ST_Distance_Sphere(point(#{longitude}, #{latitude}), point(point_lon, point_lat)) < = #{orderDistance} </if> <if test="query.pointName != null and query.pointName != ''"> and xp.point_name like concat('%',#{query.pointName},'%') xp-robotaxi-map-boot/src/main/resources/mapper/XpStationMapper.xml
@@ -4,10 +4,13 @@ <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpStation"> select a.* select a.*,b.operation_strategy as fence_operation_strategy from xp_station a inner join xp_electronic_fence b on a.electronic_id = b.id and b.is_deleted = 0 where a.is_deleted = 0 <if test="query.id != null"> and a.id = #{query.id} </if> <if test="query.ids != null"> and a.id in <foreach item="id" collection="query.ids" open="(" separator="," close=")"> @@ -47,6 +50,12 @@ <if test="query.updateEndTime != null and query.updateEndTime!=''"> and #{query.updateEndTime} >= a.update_time </if> <if test="query.stationPointNum != null and query.stationPointNum!=''"> and ( FIND_IN_SET( (SELECT COUNT(xp.id) FROM xp_point xp WHERE xp.is_deleted=0 and xp.station_id = a.id ),#{query.stationPointNum}) ) </if> GROUP BY a.id <choose> <when test="query.createSort == 1 or query.createSort == 2 or query.updateSort == 1 or query.updateSort == 2"> xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.operation.XpActivityDto; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.model.operation.XpActicityStrategy; @@ -13,7 +14,6 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.operation.mapper.XpActicityMapper; import com.xiaopeng.operation.service.IXpActicityService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.operation.service.IXpActicityStrategyService; import com.xiaopeng.operation.service.IXpActicityUserService; import com.xiaopeng.operation.service.IXpActivityNoticeService; @@ -21,11 +21,9 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.function.Function; import java.util.stream.Collectors; xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -138,7 +138,7 @@ */ @Scheduled(cron = "0/5 * * * * ?") public void taskOrder() { System.out.println("5秒执行一次"); // System.out.println("5秒执行一次"); Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID); for (String name : quoteMatchName) { String firstElement = redisService.getFirstElement(name); @@ -168,7 +168,7 @@ */ @Scheduled(cron = "0/5 * * * * ?") public void taskOrder_targeted() { System.out.println("5秒执行一次"); // System.out.println("5秒执行一次"); Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID); for (String name : quoteMatchName) { String firstElement = redisService.getFirstElement(name); xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -3853,13 +3853,20 @@ return true; } } RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin); if(routeVo.getDistance() <sylc){ isCancel = true; try { RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin); if(routeVo.getDistance() <sylc){ isCancel = true; } if(routeVo.getDuration() < sysj){ isCancel = true; } } catch (Exception e) { log.error("获取两个点位车的距离错误",e); throw new ServiceException("获取两个点位车的距离错误"); } if(routeVo.getDuration() < sysj){ isCancel = true; } return isCancel; }