package com.xiaopeng.operation.controller;
|
|
|
import cn.hutool.core.lang.Snowflake;
|
import cn.hutool.core.util.IdUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.xiaopeng.api.dto.operation.CruisePointDto;
|
import com.xiaopeng.api.dto.operation.NewCruiseOrderDto;
|
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
|
import com.xiaopeng.api.model.operation.XpCruisePlan;
|
import com.xiaopeng.api.model.operation.XpCruisePlanPoint;
|
import com.xiaopeng.api.model.operation.XpCruisePlanVehicle;
|
import com.xiaopeng.api.model.operation.XpPoint;
|
import com.xiaopeng.api.model.order.XpCruiseOrder;
|
import com.xiaopeng.common.core.domain.R;
|
import com.xiaopeng.common.core.web.page.PageInfo;
|
import com.xiaopeng.common.log.annotation.AdminOperationLog;
|
import com.xiaopeng.common.log.enums.AdminBusinessType;
|
import com.xiaopeng.common.log.enums.AdminOperationType;
|
import com.xiaopeng.operation.dto.XpCruisePlanAddDTO;
|
import com.xiaopeng.operation.dto.XpCruisePlanEditDTO;
|
import com.xiaopeng.operation.query.CruisePlanQuery;
|
import com.xiaopeng.operation.service.IXpCruisePlanPointService;
|
import com.xiaopeng.operation.service.IXpCruisePlanService;
|
import com.xiaopeng.operation.service.IXpCruisePlanVehicleService;
|
import com.xiaopeng.operation.service.XpPointService;
|
import com.xiaopeng.operation.vo.XpCruisePlanDetailVO;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.context.annotation.Lazy;
|
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
import org.springframework.validation.annotation.Validated;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import javax.annotation.Resource;
|
import javax.validation.Valid;
|
|
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.RequestParam;
|
import io.swagger.annotations.ApiParam;
|
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.stream.Collectors;
|
import com.xiaopeng.common.log.annotation.AdminOperationLog;
|
import com.xiaopeng.common.log.enums.AdminBusinessType;
|
import com.xiaopeng.common.log.enums.AdminOperationType;
|
|
/**
|
* <p>
|
* 巡游计划 前端控制器
|
* </p>
|
*
|
* @author mitao
|
* @since 2026-02-26
|
*/
|
@Validated
|
@RestController
|
@RequiredArgsConstructor(onConstructor_ = @Lazy)
|
public class XpCruisePlanController {
|
private final IXpCruisePlanService xpCruisePlanService;
|
private final IXpCruisePlanVehicleService xpCruisePlanVehicleService;
|
private final IXpCruisePlanPointService xpCruisePlanPointService;
|
private final XpPointService pointService;
|
private final XpVehicleClient xpVehicleClient;
|
|
@Resource(name = "hutoolSnowflake")
|
private Snowflake snowflake;
|
|
@ApiOperation(value = "获取巡游计划分页列表", tags = {"管理后台-巡游计划"})
|
@PostMapping(value = {"/api/v1/xp-cruise-plan/pageList"})
|
public R<PageInfo<XpCruisePlan>> getPageList(@RequestBody CruisePlanQuery query) {
|
return R.ok(xpCruisePlanService.getPageList(query));
|
}
|
|
@ApiOperation(value = "新增巡游计划", tags = {"管理后台-巡游计划"})
|
@PostMapping(value = {"/api/v1/xp-cruise-plan/add"})
|
@AdminOperationLog(
|
businessType = AdminBusinessType.CRUISE_PLAN,
|
operationType = AdminOperationType.ADD,
|
content = "新增巡游计划",
|
appendRequestData = true
|
)
|
public R<?> add(@Valid @RequestBody XpCruisePlanAddDTO dto) {
|
xpCruisePlanService.add(dto);
|
return R.ok();
|
}
|
|
@ApiOperation(value = "编辑巡游计划", tags = {"管理后台-巡游计划"})
|
@PostMapping(value = {"/api/v1/xp-cruise-plan/edit"})
|
@AdminOperationLog(
|
businessType = AdminBusinessType.CRUISE_PLAN,
|
operationType = AdminOperationType.EDIT,
|
content = "编辑巡游计划",
|
appendRequestData = true
|
)
|
public R<?> edit(@Valid @RequestBody XpCruisePlanEditDTO dto) {
|
xpCruisePlanService.edit(dto);
|
return R.ok();
|
}
|
|
@ApiOperation(value = "删除巡游计划", tags = {"管理后台-巡游计划"})
|
@DeleteMapping(value = {"/api/v1/xp-cruise-plan/deleteById/{id}"})
|
@AdminOperationLog(
|
businessType = AdminBusinessType.CRUISE_PLAN,
|
operationType = AdminOperationType.DELETE,
|
contentExpression = "'删除巡游计划,id=' + #p0",
|
appendRequestData = false
|
)
|
public R<?> deleteById(@ApiParam(name = "id", value = "巡游计划ID") @PathVariable Long id) {
|
xpCruisePlanService.deleteById(id);
|
return R.ok();
|
}
|
|
@ApiOperation(value = "巡游计划详情", tags = {"管理后台-巡游计划"})
|
@GetMapping(value = {"/api/v1/xp-cruise-plan/detail"})
|
public R<XpCruisePlanDetailVO> detail(@ApiParam(name = "id", value = "巡游计划ID") @RequestParam Long id) {
|
return R.ok(xpCruisePlanService.detail(id));
|
}
|
|
|
/**
|
* 获取车辆下个点位
|
* @return
|
*/
|
@PostMapping("/logan/inner/cruise/getCruisePoint")
|
public R<XpCruiseOrder> getCruisePoint(@RequestBody CruisePointDto dto) {
|
// 先找计划
|
XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, dto.getVehicleId()));
|
if (plan == null) {
|
return R.fail("没有找到对应的计划");
|
}
|
// 找对应的多个点位
|
List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
|
// 找到现在这个点位
|
// 根据dto的pointId 是第几个
|
int index = 0;
|
for (int i = 0; i < planPointList.size(); i++) {
|
if (planPointList.get(i).getPointId().equals(dto.getPointId())) {
|
index = i;
|
break;
|
}
|
}
|
XpCruiseOrder newXpCruiseOrder = dto.getNewXpCruiseOrder();
|
XpCruisePlanPoint xpCruisePlanPoint = null;
|
// 判断是否是最后一个 是则往前一个 否找下一个
|
if (index == planPointList.size() - 1) {
|
// 最后一个 找上一个
|
xpCruisePlanPoint = planPointList.get(index - 1);
|
newXpCruiseOrder.setOrderReverse(2);
|
} else if (index == 0) {
|
// 第一个 找下一个
|
xpCruisePlanPoint = planPointList.get(index + 1);
|
newXpCruiseOrder.setOrderReverse(1);
|
} else {
|
// 中间点位
|
if (dto.getOrderReverse() == 1) {
|
// 正向 找下一个
|
xpCruisePlanPoint = planPointList.get(index + 1);
|
newXpCruiseOrder.setOrderReverse(1);
|
} else {
|
// 反向找上一个
|
xpCruisePlanPoint = planPointList.get(index - 1);
|
newXpCruiseOrder.setOrderReverse(2);
|
}
|
}
|
Long pointId = xpCruisePlanPoint.getPointId();
|
XpPoint point = pointService.getById(pointId);
|
|
newXpCruiseOrder.setEndPointId(pointId);
|
newXpCruiseOrder.setEndPointName(point.getPointName());
|
newXpCruiseOrder.setEndLon(point.getPointLon());
|
newXpCruiseOrder.setEndLat(point.getPointLat());
|
newXpCruiseOrder.setMissionId(xpCruisePlanPoint.getCruisePlanId());
|
|
|
return R.ok(newXpCruiseOrder);
|
}
|
|
/**
|
* 获取巡游计划
|
* @param vehicleId
|
* @return
|
*/
|
@PostMapping("/logan/inner/cruise/getCruisePlan")
|
public R<XpCruisePlanVehicle> getCruisePlan(@RequestParam Long vehicleId) {
|
XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, vehicleId));
|
return R.ok(plan);
|
}
|
|
|
/**
|
* 获取巡游计划点位列表
|
* @param vehicleId
|
* @return
|
*/
|
@PostMapping("/logan/inner/cruise/getCruisePlanPointList")
|
public R<List<XpCruisePlanPoint>> getCruisePlanPointList(@RequestParam Long vehicleId) {
|
// 先找计划
|
XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, vehicleId));
|
// 找对应的多个点位
|
List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
|
return R.ok(planPointList);
|
}
|
|
|
|
|
/**
|
* 获取巡游订单数据
|
* @return
|
*/
|
@PostMapping("/logan/inner/cruise/getNewCruiseOrder")
|
public R<XpCruiseOrder> getNewCruiseOrder(@RequestBody NewCruiseOrderDto dto) {
|
|
// 先找计划
|
XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, dto.getVehicleId()));
|
// 找对应的多个点位
|
List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
|
|
|
|
XpCruiseOrder newXpCruiseOrder = new XpCruiseOrder();
|
newXpCruiseOrder.setFleetId(dto.getFleetId());
|
newXpCruiseOrder.setVehicleId(dto.getVehicleId());
|
newXpCruiseOrder.setVehicleVin(dto.getVehicleVin());
|
newXpCruiseOrder.setOrderType(1);
|
newXpCruiseOrder.setMissionId(plan.getCruisePlanId());
|
newXpCruiseOrder.setStatus(1);
|
newXpCruiseOrder.setOrderReverse(1);
|
newXpCruiseOrder.setXpuTaskId(snowflake.nextId() + "");
|
|
GeoJsonPoint point = dto.getPoint();
|
|
// 起点
|
newXpCruiseOrder.setStartLon(point.getX());
|
newXpCruiseOrder.setStartLat(point.getY());
|
|
// 终点
|
XpCruisePlanPoint endCruisePlanPoint = planPointList.get(0);
|
Long endPointId = endCruisePlanPoint.getPointId();
|
XpPoint endPoint = pointService.getById(endPointId);
|
newXpCruiseOrder.setEndPointId(endPointId);
|
newXpCruiseOrder.setEndPointName(endPoint.getPointName());
|
newXpCruiseOrder.setEndLon(endPoint.getPointLon());
|
newXpCruiseOrder.setEndLat(endPoint.getPointLat());
|
|
|
|
return R.ok(newXpCruiseOrder);
|
}
|
|
|
/**
|
* 获取车辆返回点位
|
* @param xpCruiseOrder
|
* @return
|
*/
|
@PostMapping("/logan/inner/cruise/findReturnCruisePoint")
|
public R<XpCruiseOrder> findReturnCruisePoint(@RequestBody XpCruiseOrder xpCruiseOrder) {
|
// 先找计划
|
XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, xpCruiseOrder.getVehicleId()));
|
if(null == plan){
|
return R.fail("没有巡游计划,执行收车失败");
|
}
|
// 找对应的多个点位
|
List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
|
|
XpPoint xpPoint = pointService.list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getParkingPoint, 1).in(XpPoint::getId, planPointList.stream().map(XpCruisePlanPoint::getPointId).collect(Collectors.toList()))).get(0);
|
xpCruiseOrder.setEndPointId(xpPoint.getId());
|
xpCruiseOrder.setEndPointName(xpPoint.getPointName());
|
xpCruiseOrder.setEndLon(xpPoint.getPointLon());
|
xpCruiseOrder.setEndLat(xpPoint.getPointLat());
|
xpCruiseOrder.setMissionId(plan.getCruisePlanId());
|
return R.ok(xpCruiseOrder);
|
}
|
|
/**
|
* 判断点位ID列表是否存在关联的巡游计划点位(内部接口)
|
*/
|
@PostMapping("/logan/inner/cruise/existsCruisePlanPointByPointIds")
|
public R<Boolean> existsCruisePlanPointByPointIds(@RequestBody List<Long> pointIds) {
|
List<Long> distinctPointIds = pointIds == null
|
? java.util.Collections.emptyList()
|
: pointIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
if (distinctPointIds.isEmpty()) {
|
return R.ok(Boolean.FALSE);
|
}
|
XpCruisePlanPoint exists = xpCruisePlanPointService.getOne(
|
new LambdaQueryWrapper<XpCruisePlanPoint>()
|
.in(XpCruisePlanPoint::getPointId, distinctPointIds)
|
.last("limit 1")
|
);
|
return R.ok(exists != null);
|
}
|
}
|