package com.xiaopeng.order.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.dto.QueryOrderRouteDTO;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.order.FareBreakdownVo;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
import com.xiaopeng.api.vo.order.XpPointInfoVo;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.WebUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.order.mangodb.model.OrderTrajectory;
import com.xiaopeng.order.model.dto.XpOrderCommentDto;
import com.xiaopeng.order.model.dto.XpOrderPayDto;
import com.xiaopeng.order.model.exportExcel.XpOrderExportExcel;
import com.xiaopeng.order.model.query.XpHistoryOrderListQuery;
import com.xiaopeng.order.model.query.XpOrderPageQuery;
import com.xiaopeng.order.model.dto.XpOrderOperateDTO;
import com.xiaopeng.order.model.dto.XpOrderReassignDTO;
import com.xiaopeng.order.model.vo.XpOrderDetailVO;
import com.xiaopeng.order.model.vo.XpOrderHistoryVO;
import com.xiaopeng.order.model.vo.XpOrderPageVO;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.vo.OrderDetailVo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
/**
*
* 订单 前端控制器
*
*
* @author mitao
* @since 2026-02-03
*/
@RestController
@Api(tags = "订单")
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpOrderController {
private final IXpOrderService xpOrderService;
private final RedisService redisService;
/**
* 获取订单统计数据(内部接口)
*
* @param query 查询参数
* @return 订单统计数据
*/
@ApiOperation(value = "获取订单统计数据", tags = {"内部接口"})
@PostMapping("/inner/order/statistics")
public R getOrderStatistics(@RequestBody StatisticsQueryDTO query) {
return R.ok(xpOrderService.getOrderStatistics(query));
}
/**
* 查询是否有未支付订单 或 正在进行的订单
* 返回0 可以下单 1有进行中的订单 8有待支付的
*/
@PostMapping("/inner/order/has-unpaid-order")
@ApiOperation(value = "查询是否有未支付订单 或 正在进行的订单", tags = {"内部接口"})
public R hasUnPaodOrder(String uid){
List list = xpOrderService.list(new LambdaQueryWrapper().eq(XpOrder::getAppUserId, Long.parseLong(uid)).in(XpOrder::getStatus, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)));
if(!list.isEmpty()){
return R.ok(list.get(0).getId());
}
return R.ok(0l);
}
/**
* 通过订单id查询订单信息
*
* @param orderId 订单id
* @return 订单详情
*/
@PostMapping("/inner/order/queryOrderById")
public R queryOrderById(@RequestParam Long orderId){
return R.ok(xpOrderService.getById(orderId));
}
@PostMapping("/inner/order/queryOrderByOrderNo")
public R queryOrderByOrderNo(@RequestParam String orderNo){
return R.ok(xpOrderService.getOne(new LambdaQueryWrapper().eq(XpOrder::getOrderNumber, orderNo)));
}
/**
* 获取订单数量
*
* @return 订单数量
*/
@PostMapping("/inner/order/getOrderNum")
public R getOrderNum(@RequestBody GetOrderNumDto dto){
return R.ok(xpOrderService.getOrderNum(dto));
}
/**
* 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据
*/
@PostMapping("/inner/order/popOrder")
public R> popOrder(@RequestBody PopOrderDto dto){
xpOrderService.popOrder(dto);
return R.ok();
}
/**
* 修改订单信息
*
* @param xpOrder 订单信息
*/
@PostMapping("/inner/order/updateOrder")
public R> updateOrder(@RequestBody XpOrder xpOrder){
return xpOrderService.updateById(xpOrder)?R.ok():R.fail();
}
/**
* 新增订单
*
* @param xpOrder 订单信息
* @return 订单ID
*/
@PostMapping("/inner/order/addOrder")
public R addOrder(@RequestBody XpOrder xpOrder){
boolean save = xpOrderService.addOrder(xpOrder);
if(!save){
return R.fail("新增失败");
}
return R.ok(xpOrder.getId());
}
/**
* 取消订单
*
* @param orderId 订单ID
* @return 操作结果
*/
@PostMapping("/inner/order/cancelOrder")
public R> cancelOrder(@RequestParam("orderId") String orderId){
xpOrderService.cancelOrder(orderId);
return R.ok();
}
/**
* 订单分页列表
*
* @param query 分页查询参数
* @return 分页结果
*/
@ApiOperation(value = "订单分页列表", tags = {"管理后台-交易管理-订单管理"})
@PostMapping("/api/v1/order/pageList")
public R> pageList(@Validated @RequestBody XpOrderPageQuery query) {
PageInfo pageInfo = xpOrderService.pageList(query);
return R.ok(pageInfo);
}
/**
* 订单详情
*
* @param id 订单ID
* @return 订单详情
*/
@ApiOperation(value = "订单详情", tags = {"管理后台-交易管理-订单管理"})
@GetMapping("/api/v1/order/queryById")
public R queryById(@ApiParam(value = "订单id", required = true) @RequestParam Long id) {
XpOrderDetailVO detail = xpOrderService.getOrderDetail(id);
return R.ok(detail);
}
/**
* 删除订单
*
* @param id 订单ID
* @return 操作结果
*/
@ApiOperation(value = "删除订单", tags = {"管理后台-交易管理-订单管理"})
@DeleteMapping("/api/v1/order/deleteById")
public R> deleteById(@ApiParam(value = "订单id", required = true) @RequestParam Long id) {
xpOrderService.deleteOrder(id);
return R.ok();
}
/**
* 订单导出
*
* @param query 查询参数
*/
@ApiOperation(value = "订单导出", tags = {"管理后台-交易管理-订单管理"})
@PostMapping("/api/v1/order/exportExcel")
public void exportExcel(@RequestBody XpOrderPageQuery query) {
// 1. 查询导出数据
List dataList = xpOrderService.exportList(query);
// 2. 转换为导出对象
List exportList = BeanUtil.copyToList(dataList, XpOrderExportExcel.class);
// 3. 生成 Excel
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpOrderExportExcel.class, exportList);
// 4. 输出到响应流
HttpServletResponse response = WebUtils.response();
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
ServletOutputStream outputStream = null;
try {
String fileName = URLEncoder.encode("订单列表.xls", "utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
outputStream = response.getOutputStream();
workbook.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 取消/关闭订单
*
* @param dto 操作请求参数
* @return 操作结果
*/
@ApiOperation(value = "取消/关闭订单", tags = {"管理后台-交易管理-订单管理"})
@PostMapping("/api/v1/order/cancelAndCloseById")
public R> cancelAndCloseById(@Validated @RequestBody XpOrderOperateDTO dto) {
xpOrderService.cancelOrCloseOrder(dto.getOrderId(), dto.getType());
return R.ok();
}
/**
* 改派订单
*
* @param dto 改派请求参数
* @return 操作结果
*/
@ApiOperation(value = "改派订单", tags = {"管理后台-交易管理-订单管理"},notes = "车辆列表在maintenance服务")
@PostMapping("/api/v1/order/reassignById")
public R> reassignById(@Validated @RequestBody XpOrderReassignDTO dto) {
xpOrderService.reassignOrder(
dto.getOrderId(),
dto.getVehicleId(),
dto.getReassignReason()
);
return R.ok();
}
/**
* 获取用户快捷胶囊 历史 时段 终点高点
*/
@ApiOperation(value = "获取用户快捷胶囊 历史 时段 终点高点", tags = {"小程序-获取用户快捷胶囊 历史 时段 终点高点"})
@GetMapping("/api/v1/mini-program/order/getUserQuickCapsule")
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R getUserQuickCapsule(HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.getUserQuickCapsule(uid));
}
/**
* 获取订单详情
*/
@PutMapping("/api/v1/mini-program/order/orderDetail/{orderId}")
@ApiOperation(value = "获取订单详情", tags = {"小程序-获取订单详情"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R orderDetail(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
;
return R.ok(xpOrderService.orderDetail(orderId,uid));
}
/**
* 获取历史下单成功起点10条数据列表
*/
@ApiOperation(value = "获取历史下单成功起点10条数据列表", tags = {"小程序-获取历史下单成功起点10条数据列表"})
@GetMapping("/base/v1/mini-program/history/startPoints")
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R> getHistoryStartPoints(double lon,double lat,HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.getHistoryStartPoints(uid,lon,lat));
}
/**
* 获取历史下单成功终点点10条数据列表
*/
@ApiOperation(value = "获取历史下单成功终点10条数据列表", tags = {"小程序-获取历史下单成功终点10条数据列表"})
@GetMapping("/base/v1/mini-program/history/endPoints")
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R> getHistoryEndPoints(double lon, double lat, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.getHistoryEndPoints(uid,lon,lat));
}
/**
* 获取正在进行中的订单
*/
@ApiOperation(value = "获取正在进行中的订单", tags = {"小程序-获取正在进行中的订单"})
@GetMapping("/api/v1/mini-program/order/active")
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R getActiveOrder(HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.getActiveOrder(uid));
}
/**
* 查询历史订单列表
*/
@ApiOperation(value = "查询历史订单列表", tags = {"小程序-查询历史订单列表"})
@PostMapping("/api/v1/mini-program/order/history/list")
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R getHistoryOrderList(@RequestBody XpHistoryOrderListQuery query, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.getHistoryOrderList(query, uid));
}
/**+
* 取消订单
*/
@PutMapping("/api/v1/mini-program/order/cancel/{orderId}")
@ApiOperation(value = "取消订单", tags = {"小程序-取消订单"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R cancelOrder(@PathVariable("orderId") Long orderId,HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
xpOrderService.cancelOrder(orderId,uid);
return R.ok();
}
/**+
* 手动结束订单
*/
@PutMapping("/api/v1/mini-program/order/endTrip/{orderId}")
@ApiOperation(value = "结束行程", tags = {"小程序-结束行程"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R endTrip(@PathVariable("orderId") Long orderId,HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
try {
xpOrderService.endTrip(orderId,uid);
}catch (Exception e){
return R.ok();
}
return R.ok();
}
/**+
* 获取行程费用明细
*/
@PutMapping("/api/v1/mini-program/order/fare-breakdown/{orderId}")
@ApiOperation(value = "获取行程费用明细", tags = {"小程序-获取行程费用明细"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R fareBreakdown(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return xpOrderService.fareBreakdown(orderId,uid);
}
/**+
* 获取行程费用明细
*/
@PutMapping("/api/v1/mini-program/order/feeDescription/{orderId}")
@ApiOperation(value = "获取费用说明", tags = {"小程序-获取费用说明"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R feeDescription(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return xpOrderService.feeDescription(orderId,uid);
}
/**
* 订单评价
*/
@PostMapping("/api/v1/mini-program/order/payment")
@ApiOperation(value = "发起支付", tags = {"小程序-发起支付"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R payment(@Validated @RequestBody XpOrderPayDto dto, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
return xpOrderService.payment(dto,uid);
}
/**
* 订单评价
*/
@PostMapping("/api/v1/mini-program/order/comment")
@ApiOperation(value = "订单评价", tags = {"小程序-订单评价"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R comment(@Validated @RequestBody XpOrderCommentDto dto, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
xpOrderService.comment(dto,uid);
return R.ok();
}
/**
* 订单状态修改-车控消息推送我方调用(内部接口)
*/
@ApiOperation(value = "订单状态推送修改")
@PostMapping("/inner/v1/order/updateOrderStatus")
public R updateOrderStatus(@RequestParam Long orderId,
@RequestParam Integer status) {
return xpOrderService.updateOrderStatus(orderId,status);
}
/**
* 业务流程-通过订单id查询车辆信息
*/
@ApiOperation(value = "通过订单id查询车辆信息", tags = {"小程序-业务流程"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
@GetMapping("/api/v1/mini-program/order/queryVehicleByOrderId")
public R queryVehicleByOrderId(@RequestParam Long orderId, HttpServletRequest request) {
String uid = request.getHeader("XP-Uid");
return R.ok(xpOrderService.queryVehicleByOrderId(orderId,uid));
}
/**
* 订单车辆定位实时存储-订单车辆定位实时存储(内部接口)
*/
@ApiOperation(value = "订单车辆定位实时存储")
@PostMapping("/inner/v1/order/saveVehicleLocation")
public R saveVehicleLocation(@RequestBody OrderTrajectory orderTrajectory) {
xpOrderService.saveVehicleLocation(orderTrajectory);
return R.ok();
}
/**
* 订单查询实时轨迹路线
*/
@ApiOperation(value = "订单查询实时轨迹路线")
@PostMapping("/api/v1/mini-program/order/queryOrderRoute")
public R queryOrderRoute(@Validated @RequestBody QueryOrderRouteDTO dto, HttpServletRequest request) {
String uid = request.getHeader("XP-Uid");
// 查询订单信息
// XpOrder xpOrder = xpOrderService.getById(dto.getOrderId());
// 获取路线规划
RouteVo routeVo = redisService.getCacheObject(CacheConstants.ORDER_ROUTE_CAPTURE + "_" + dto.getOrderId() + "_" +dto.getRouteType());
return R.ok(routeVo);
}
}