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;
|
|
/**
|
* <p>
|
* 点位管理 服务实现类
|
* </p>
|
*
|
* @author liu
|
* @author WuGuanFengYue
|
* @since 2026-02-03
|
*/
|
@Service
|
public class XpTestPointServiceImpl extends ServiceImpl<XpTestPointMapper, XpTestPoint> 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<XpTestPoint> pointMap(PointMapQuery query) {
|
List<XpTestPoint> list = this.baseMapper.pointMap(query);
|
return list;
|
}
|
|
@Override
|
public List<XpTestPoint> listAll(PointListQuery query) {
|
if(StringUtils.hasLength(query.getOperationStatus())){
|
String[] split = query.getOperationStatus().split(",");
|
List<Integer> statusIds = new ArrayList<>();
|
for (String s : split) {
|
statusIds.add(Integer.valueOf(s));
|
}
|
query.setOperationStatusIds(statusIds);
|
}
|
List<XpTestPoint> list = this.baseMapper.listAll(query);
|
return list;
|
}
|
|
@Override
|
public List<XpHistoryStartPointsVo> getHistoryStartPoints(HistoryStartPointsDto historyStartPointsDto) {
|
List<XpTestPoint> xpPoints = this.baseMapper.selectBatchIds(historyStartPointsDto.getPointIds());
|
ArrayList<XpHistoryStartPointsVo> resultList = new ArrayList<>(10);
|
|
LocalTime now = LocalTime.now();
|
List<Long> areaIds = xpPoints.stream().map(XpTestPoint::getElectronicAreaId).collect(Collectors.toList());
|
List<XpElectronicFenceArea> xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds);
|
List<Long> fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList());
|
|
List<XpElectronicFence> 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<XpHistoryEndPointsVo> getHistoryEndPoints(HistoryEndPointsDto historyEndPointsDto) {
|
List<XpTestPoint> xpPoints = this.baseMapper.selectBatchIds(historyEndPointsDto.getPointIds());
|
ArrayList<XpHistoryEndPointsVo> resultList = new ArrayList<>(10);
|
|
LocalTime now = LocalTime.now();
|
List<Long> areaIds = xpPoints.stream().map(XpTestPoint::getElectronicAreaId).collect(Collectors.toList());
|
List<XpElectronicFenceArea> xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds);
|
List<Long> fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList());
|
|
List<XpElectronicFence> 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<XpTestPoint> pageList(PointPageListListQuery query) {
|
PageInfo<XpTestPoint> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize());
|
List<XpTestPoint> 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;
|
}
|
}
|