“mitao”
2026-02-12 d09e1c104aed44b4c2cc3c620ef28f4f5a2ec13a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
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.order.GetOrderNumDto;
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.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.domain.R;
import com.xiaopeng.common.core.utils.WebUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
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.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;
 
/**
 * <p>
 * 订单 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2026-02-03
 */
@RestController
@Api(tags = "订单")
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpOrderController {
 
    private final IXpOrderService xpOrderService;
 
    /**
     * 获取订单统计数据(内部接口)
     *
     * @param query 查询参数
     * @return 订单统计数据
     */
    @ApiOperation(value = "获取订单统计数据", tags = {"内部接口"})
    @PostMapping("/inner/order/statistics")
    public R<OrderStatisticsDTO> getOrderStatistics(@RequestBody StatisticsQueryDTO query) {
        return R.ok(xpOrderService.getOrderStatistics(query));
    }
 
 
    /**
     * 查询是否有未支付订单 或 正在进行的订单
     * 返回0 可以下单  1有进行中的订单  8有待支付的
     */
    @PostMapping("/inner/order/has-unpaid-order")
    @ApiOperation(value = "查询是否有未支付订单 或 正在进行的订单", tags = {"内部接口"})
    public R<Long> hasUnPaodOrder(String uid){
        List<XpOrder> list = xpOrderService.list(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, 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<XpOrder> queryOrderById(@RequestParam Long orderId){
        return R.ok(xpOrderService.getById(orderId));
    }
 
    @PostMapping("/inner/order/queryOrderByOrderNo")
    public R<XpOrder> queryOrderByOrderNo(@RequestParam String orderNo){
        return R.ok(xpOrderService.getOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getOrderNumber, orderNo)));
    }
 
    /**
     * 获取订单数量
     *
     * @return 订单数量
     */
    @PostMapping("/inner/order/getOrderNum")
    public  R<Integer> getOrderNum(@RequestBody GetOrderNumDto dto){
        return R.ok(xpOrderService.getOrderNum(dto));
    }
 
    /**
     * 新增订单
     *
     * @param xpOrder 订单信息
     * @return 订单ID
     */
    @PostMapping("/inner/order/addOrder")
    public R<Long> 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(String orderId){
        xpOrderService.cancelOrder(orderId);
        return R.ok();
    }
 
    /**
     * 订单分页列表
     *
     * @param query 分页查询参数
     * @return 分页结果
     */
    @ApiOperation(value = "订单分页列表", tags = {"管理后台-交易管理-订单管理"})
    @PostMapping("/api/v1/order/pageList")
    public R<PageInfo<XpOrderPageVO>> pageList(@Validated @RequestBody XpOrderPageQuery query) {
        PageInfo<XpOrderPageVO> pageInfo = xpOrderService.pageList(query);
        return R.ok(pageInfo);
    }
 
    /**
     * 订单详情
     *
     * @param id 订单ID
     * @return 订单详情
     */
    @ApiOperation(value = "订单详情", tags = {"管理后台-交易管理-订单管理"})
    @GetMapping("/api/v1/order/queryById")
    public R<XpOrderDetailVO> 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<XpOrderPageVO> dataList = xpOrderService.exportList(query);
 
        // 2. 转换为导出对象
        List<XpOrderExportExcel> 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<XpPointInfoVo> getUserQuickCapsule(HttpServletRequest  request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        return R.ok(xpOrderService.getUserQuickCapsule(uid));
 
    }
 
 
    /**
     * 获取历史下单成功起点10条数据列表
     */
    @ApiOperation(value = "获取历史下单成功起点10条数据列表", tags = {"小程序-获取历史下单成功起点10条数据列表"})
    @GetMapping("/base/v1/mini-program/history/startPoints")
    @XpClientCheck(checkToken = false, checkOtpToken = true)
    public R<List<XpHistoryStartPointsVo>> 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<List<XpHistoryEndPointsVo>> 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<XpOrderDetailVO> 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<XpOrderHistoryVO> 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/order/endTrip/{order_id}")
    @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");
        xpOrderService.endTrip(orderId,uid);
        return R.ok();
    }
    /**+
     * 获取行程费用明细
     */
 
    @PutMapping("/api/v1/order/fare-breakdown/{order_id}")
    @ApiOperation(value = "获取行程费用明细", tags = {"小程序-获取行程费用明细"})
    @XpClientCheck(checkToken = false, checkOtpToken = true)
    public R<FareBreakdownVo> fareBreakdown(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        return xpOrderService.fareBreakdown(orderId,uid);
    }
    /**
     * 订单评价
     */
    @PostMapping("/api/v1/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<String> 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<XpVehicle> 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<String> saveVehicleLocation(@RequestBody OrderTrajectory orderTrajectory) {
        xpOrderService.saveVehicleLocation(orderTrajectory);
        return R.ok();
    }
 
}