package com.xiaopeng.map.service.serviceimpl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.operation.PointMapQuery; import com.xiaopeng.api.dto.order.HistoryEndPointsDto; import com.xiaopeng.api.dto.order.HistoryStartPointsDto; import com.xiaopeng.api.model.map.XpTestPoint; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpElectronicFenceArea; import com.xiaopeng.api.model.operation.XpSystemSetting; import com.xiaopeng.api.query.operation.PointListQuery; import com.xiaopeng.api.query.operation.PointPageListListQuery; import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo; import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.map.dto.NearestDto; import com.xiaopeng.map.mapper.XpSystemSettingMapper; import com.xiaopeng.map.mapper.XpTestPointMapper; import com.xiaopeng.map.service.XpElectronicFenceAreaService; import com.xiaopeng.map.service.XpElectronicFenceService; import com.xiaopeng.map.service.XpTestPointService; 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.NearestNextVo; import com.xiaopeng.map.vo.NearestVo; import com.xiaopeng.map.vo.OrderDistanceVo; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; /** *

* 点位管理 服务实现类 *

* * @author liu * @author WuGuanFengYue * @since 2026-02-03 */ @Service public class XpTestPointServiceImpl extends ServiceImpl implements XpTestPointService { @Resource private XpSystemSettingMapper xpSystemSettingMapper; @Resource private RedisService redisService; @Resource private HolidayUtil holidayUtil; @Resource private XpElectronicFenceAreaService xpElectronicFenceAreaService; @Resource private XpElectronicFenceService xpElectronicFenceService; 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 pointMap(PointMapQuery query) { List list = this.baseMapper.pointMap(query); return list; } @Override public List listAll(PointListQuery query) { if(StringUtils.hasLength(query.getOperationStatus())){ String[] split = query.getOperationStatus().split(","); List statusIds = new ArrayList<>(); for (String s : split) { statusIds.add(Integer.valueOf(s)); } query.setOperationStatusIds(statusIds); } List list = this.baseMapper.listAll(query); return list; } @Override public List getHistoryStartPoints(HistoryStartPointsDto historyStartPointsDto) { List xpPoints = this.baseMapper.selectBatchIds(historyStartPointsDto.getPointIds()); ArrayList resultList = new ArrayList<>(10); LocalTime now = LocalTime.now(); List areaIds = xpPoints.stream().map(XpTestPoint::getElectronicAreaId).collect(Collectors.toList()); List xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds); List fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList()); List xpElectronicFences = new ArrayList<>(); if (CollUtil.isNotEmpty(fenceIds)) { xpElectronicFences = xpElectronicFenceService.listByIds(fenceIds); } for (XpTestPoint xpPoint : xpPoints) { if(xpPoint.getOperationStatus()!=2){ continue; } Integer operationType = xpPoint.getOperationType(); if(1 == operationType){ //与运营区同步 XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreas.stream().filter(s -> s.getId().equals(xpPoint.getElectronicAreaId())).findFirst().orElse(null); if(null == xpElectronicFenceArea){ // 不在运营段 continue; } XpElectronicFence xpElectronicFence = xpElectronicFences.stream().filter(s -> s.getId().equals(xpElectronicFenceArea.getElectronicId())).findFirst().orElse(null); if(null == xpElectronicFence){ // 不在运营段 continue; } //失效类型 1=永不失效 2=定时失效 Integer failureType = xpElectronicFence.getFailureType(); //永不失效,但是还未到开始时间 if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){ continue; }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){ //定时失效,但是当前时间不在时间范围内 continue; } }else{ //自定义时间段 // 判断是否在时间段内 boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod()); if (!intime) { // 不在运营段 continue; } } XpHistoryStartPointsVo xpHistoryStartPointsVo = new XpHistoryStartPointsVo(); xpHistoryStartPointsVo.setOperationStatus(1); xpHistoryStartPointsVo.setName(xpPoint.getPointName()); xpHistoryStartPointsVo.setAddress(xpPoint.getPointAddress()); xpHistoryStartPointsVo.setLatitude(xpPoint.getPointLat()); xpHistoryStartPointsVo.setLongitude(xpPoint.getPointLon()); xpHistoryStartPointsVo.setId(xpPoint.getId()); double distanced = FastDistanceCalculator.distanceFast(historyStartPointsDto.getLat(), historyStartPointsDto.getLon(), xpPoint.getPointLat(), xpPoint.getPointLon()); xpHistoryStartPointsVo.setDistance(distanced); xpHistoryStartPointsVo.setTime(xpPoint.getParkingTimeLimit()); xpHistoryStartPointsVo.setElectronicAreaId(xpPoint.getElectronicAreaId()); resultList.add(xpHistoryStartPointsVo); } return resultList; } @Override public List getHistoryEndPoints(HistoryEndPointsDto historyEndPointsDto) { List xpPoints = this.baseMapper.selectBatchIds(historyEndPointsDto.getPointIds()); ArrayList resultList = new ArrayList<>(10); LocalTime now = LocalTime.now(); List areaIds = xpPoints.stream().map(XpTestPoint::getElectronicAreaId).collect(Collectors.toList()); List xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds); List fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList()); List xpElectronicFences = new ArrayList<>(); if (CollUtil.isNotEmpty(fenceIds)) { xpElectronicFences = xpElectronicFenceService.listByIds(fenceIds); } for (XpTestPoint xpPoint : xpPoints) { if(xpPoint.getOperationStatus()!=2){ continue; } Integer operationType = xpPoint.getOperationType(); if(1 == operationType){ //与运营区同步 XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreas.stream().filter(s -> s.getId().equals(xpPoint.getElectronicAreaId())).findFirst().orElse(null); if(null == xpElectronicFenceArea){ // 不在运营段 continue; } XpElectronicFence xpElectronicFence = xpElectronicFences.stream().filter(s -> s.getId().equals(xpElectronicFenceArea.getElectronicId())).findFirst().orElse(null); if(null == xpElectronicFence){ // 不在运营段 continue; } //失效类型 1=永不失效 2=定时失效 Integer failureType = xpElectronicFence.getFailureType(); //永不失效,但是还未到开始时间 if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){ continue; }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){ //定时失效,但是当前时间不在时间范围内 continue; } }else{ //自定义时间段 // 判断是否在时间段内 boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod()); if (!intime) { // 不在运营段 continue; } } XpHistoryEndPointsVo xpHistoryEndPointsVo = new XpHistoryEndPointsVo(); xpHistoryEndPointsVo.setOperationStatus(1); xpHistoryEndPointsVo.setName(xpPoint.getPointName()); xpHistoryEndPointsVo.setAddress(xpPoint.getPointAddress()); xpHistoryEndPointsVo.setLatitude(xpPoint.getPointLat()); xpHistoryEndPointsVo.setLongitude(xpPoint.getPointLon()); xpHistoryEndPointsVo.setId(xpPoint.getId()); double distanced = FastDistanceCalculator.distanceFast(historyEndPointsDto.getLat(), historyEndPointsDto.getLon(), xpPoint.getPointLat(), xpPoint.getPointLon()); xpHistoryEndPointsVo.setDistance(distanced); xpHistoryEndPointsVo.setTime(xpPoint.getParkingTimeLimit()); xpHistoryEndPointsVo.setElectronicAreaId(xpPoint.getElectronicAreaId()); resultList.add(xpHistoryEndPointsVo); } return resultList; } @Override public OrderDistanceVo getOrderDistance() { OrderDistanceVo orderDistanceVo = new OrderDistanceVo(); XpSystemSetting xpSystemSetting = xpSystemSettingMapper.selectOne(null); if (xpSystemSetting != null) { orderDistanceVo.setMaxDistance(xpSystemSetting.getOrderDistance()); orderDistanceVo.setMinDistance(xpSystemSetting.getMinOrderDistance()); orderDistanceVo.setAdsorptionDistance(xpSystemSetting.getAdsorptionDistance()); orderDistanceVo.setNearPointDistance(xpSystemSetting.getNearPointDistance()); return orderDistanceVo; } return orderDistanceVo; } @Override public PageInfo pageList(PointPageListListQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize()); List list = this.baseMapper.pageList(pageInfo,query); pageInfo.setRecords(list); return pageInfo; } @Override public Boolean nowInTimePoint(Long pointId) { XpTestPoint xpPoint = this.getById(pointId); if(null == xpPoint){ return false; } Integer operationType = xpPoint.getOperationType(); if(1 == operationType){ //与运营区同步 XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaService.getById(xpPoint.getElectronicAreaId()); if(null == xpElectronicFenceArea){ return false; } XpElectronicFence xpElectronicFence = xpElectronicFenceService.getById(xpElectronicFenceArea.getElectronicId()); if(null == xpElectronicFence){ return false; } //失效类型 1=永不失效 2=定时失效 Integer failureType = xpElectronicFence.getFailureType(); //永不失效,但是还未到开始时间 if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){ return false; }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){ //定时失效,但是当前时间不在时间范围内 return false; } }else{ //自定义时间段 // 判断是否在时间段内 boolean intime = getInTime(LocalTime.now(), xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod()); if (!intime) { return false; } } return true; } }