From 4fa9c3488e3cfd8179f31b83a056138d8f622137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E6=96=87=E9=9D=99WWW?= <15144434+wen-wenjing-www@user.noreply.gitee.com> Date: Sun, 13 Jul 2025 18:31:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=8A=B6=E6=80=81=E5=88=86?= =?UTF-8?q?=E6=9E=90=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OrderAnalysisController.java | 34 +++++++++- .../order/domain/dto/OrderAnalysisResult.java | 1 + .../modules/order/mapper/OrderMainMapper.java | 3 +- .../order/service/IOrderMainService.java | 1 + .../order/service/OrderAnalysisService.java | 4 ++ .../impl/OrderAnalysisServiceImpl.java | 63 +++++++++---------- .../service/impl/OrderMainServiceImpl.java | 10 +++ .../route/controller/CpRouteController.java | 45 +++++++++++-- .../mapper/order/OrderDetailMapper.xml | 2 +- 9 files changed, 119 insertions(+), 44 deletions(-) diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderAnalysisController.java b/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderAnalysisController.java index 2b825ed..61c81b0 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderAnalysisController.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderAnalysisController.java @@ -1,13 +1,19 @@ package com.aircraft.modules.order.controller; +import com.aircraft.modules.order.domain.OrderMain; import com.aircraft.modules.order.domain.dto.*; +import com.aircraft.modules.order.mapper.OrderMainMapper; +import com.aircraft.modules.order.service.IOrderMainService; import com.aircraft.modules.order.service.OrderAnalysisService; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import org.apache.poi.ss.formula.functions.T; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -16,10 +22,11 @@ import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Collections; import java.util.List; import java.util.regex.Pattern; -@Api(tags ="系统:订单分析") +@Api(tags = "系统:订单分析") @RestController @RequestMapping("/fmsOdOrderAnalysis") //每个接口都返回时间范围内的总订单量、订单总金额、进行中的订单量、完成的订单量、完成的订单率、 @@ -29,6 +36,8 @@ public class OrderAnalysisController { private static final Logger LOG = LoggerFactory.getLogger(OrderAnalysisController.class); @Autowired private OrderAnalysisService orderAnalysisService; + @Autowired + private IOrderMainService iOrderMainService; // 日期格式化器 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @@ -37,6 +46,26 @@ public class OrderAnalysisController { // 季度格式校验正则(yyyy-Q1~Q4) private static final Pattern QUARTER_PATTERN = Pattern.compile("^\\d{4}-Q[1-4]$"); + @ApiOperation("全部订单分析统计") + @GetMapping + public ResponseEntity> analyzeAllOrders() { + try { + // 1. 获取数据库中所有订单数据 + List allOrders = iOrderMainService.queryAllOrders(); + + // 2. 校验订单数据 + if (CollectionUtils.isEmpty(allOrders)) { + LOG.info("全部订单分析:未找到订单数据"); + return ResponseEntity.badRequest().body(null); + } + OrderAnalysisResult result = orderAnalysisService.analyzeAllOrders(allOrders); + return ResponseEntity.ok(result); + } catch (Exception e) { + LOG.error("全部订单分析失败", e); + return ResponseEntity.badRequest().body(null); + } + } + @ApiOperation("按日范围分析订单") @GetMapping("/day") //额外返回传入时间范围内的每日订单总量 @@ -169,8 +198,9 @@ public class OrderAnalysisController { LOG.error("按年分析失败,参数:startDate={}, endDate={}", startDate, endDate, e); return ResponseEntity.badRequest().body(null); } - } // 工具方法:获取季度第一天(如2025-Q1 → 2025-01-01) + } + // 工具方法:获取季度第一天(如2025-Q1 → 2025-01-01) private LocalDate getQuarterFirstDay(int year, int quarter) { int month = (quarter - 1) * 3 + 1; return LocalDate.of(year, month, 1); diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderAnalysisResult.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderAnalysisResult.java index 2e7f028..917eb9f 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderAnalysisResult.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderAnalysisResult.java @@ -13,6 +13,7 @@ public class OrderAnalysisResult { private Long noStartOrderCount; //未开始的订单量 private Long inProgressOrderCount; // 进行中的订单量 private Long completedOrderCount; // 完成的订单量 + private Long cancelOrderCount;//取消的订单量 private Double completionRate; // 完成的订单率 private PageInfo pageInfo; // 分页信息 private List orderList; // 订单列表 diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/mapper/OrderMainMapper.java b/aircraft-system/src/main/java/com/aircraft/modules/order/mapper/OrderMainMapper.java index db633ce..1fa8123 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/mapper/OrderMainMapper.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/mapper/OrderMainMapper.java @@ -4,6 +4,8 @@ import com.aircraft.modules.order.domain.OrderMain; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.springframework.stereotype.Repository; +import java.util.List; + /** *

* 订单主表 Mapper 接口 @@ -14,5 +16,4 @@ import org.springframework.stereotype.Repository; */ @Repository public interface OrderMainMapper extends BaseMapper { - } diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/IOrderMainService.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/IOrderMainService.java index 659d606..6d90445 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/IOrderMainService.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/IOrderMainService.java @@ -24,4 +24,5 @@ public interface IOrderMainService extends IService { */ List queryAll(OrderMainPageQueryDTO pageQueryDTO); + List queryAllOrders(); } diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/OrderAnalysisService.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/OrderAnalysisService.java index e9e9d5b..3930eca 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/OrderAnalysisService.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/OrderAnalysisService.java @@ -1,7 +1,9 @@ package com.aircraft.modules.order.service; +import com.aircraft.modules.order.domain.OrderMain; import com.aircraft.modules.order.domain.dto.*; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import java.time.LocalDate; @@ -16,4 +18,6 @@ public interface OrderAnalysisService { OrderAnalysisResult> analyzeByQuarterRange(LocalDate start, LocalDate end); OrderAnalysisResult> analyzeByYearRange(LocalDate start, LocalDate end); + + OrderAnalysisResult analyzeAllOrders(List allOrders); } diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java index 451e5e6..ee635a9 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java @@ -8,9 +8,7 @@ import com.aircraft.modules.order.domain.dto.*; import com.aircraft.modules.order.mapper.OrderDetailMapper; import com.aircraft.modules.order.mapper.OrderMainMapper; import com.aircraft.modules.order.service.OrderAnalysisService; -import com.aircraft.modules.route.domain.CpRoute; import com.aircraft.modules.route.mapper.CpRouteMapper; -import com.aircraft.modules.system.service.EmAreaService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.beans.factory.annotation.Autowired; @@ -46,9 +44,10 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy"); // 订单状态 - private static final Integer STATUS_NOTSTART = 0; - private static final Integer STATUS_IN_PROGRESS = 1; - private static final Integer STATUS_COMPLETED = 2; + private static final Integer STATUS_NOT_STARTED = 0;//未进行 + private static final Integer STATUS_PROCESSING = 1;//进行中 + private static final Integer STATUS_COMPLETED = 2;//已完成 + private static final Integer STATUS_CANCELED = 3;//已取消 /** @@ -217,6 +216,11 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { return buildAnalysisResult(orders, yearlyStats); } + @Override + public OrderAnalysisResult analyzeAllOrders(List allOrders) { + return buildAnalysisOrdersResult(allOrders); + } + // ====================== 通用工具方法 ====================== @@ -235,6 +239,14 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { * 构建完整的订单分析结果 */ private OrderAnalysisResult buildAnalysisResult(List orders, T timeSeriesData) { + OrderAnalysisResult result = buildAnalysisOrdersResult(orders); + // 6. 时间序列数据(日/月/季/年统计) + result.setTimeSeriesData(timeSeriesData); + return result; + } + + //处理订单返回结果 + private OrderAnalysisResult buildAnalysisOrdersResult(List orders) { OrderAnalysisResult result = new OrderAnalysisResult<>(); // 1. 基础统计指标 @@ -242,12 +254,14 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { result.setTotalOrderAmount(calculateTotalAmount(orders)); // 总金额 // 2. 状态统计 - long noStartCount=countOrdersByStatus(orders,STATUS_NOTSTART); - long inProgressCount = countOrdersByStatus(orders, STATUS_IN_PROGRESS); + long notStartCount = countOrdersByStatus(orders, STATUS_NOT_STARTED); + long progressingCount = countOrdersByStatus(orders, STATUS_PROCESSING); long completedCount = countOrdersByStatus(orders, STATUS_COMPLETED); - result.setNoStartOrderCount(noStartCount); - result.setInProgressOrderCount(inProgressCount); + long canceledCount = countOrdersByStatus(orders, STATUS_CANCELED); + result.setNoStartOrderCount(notStartCount); + result.setInProgressOrderCount(progressingCount); result.setCompletedOrderCount(completedCount); + result.setCancelOrderCount(canceledCount); // 计算完成率(避免除0) result.setCompletionRate(orders.isEmpty() ? 0D : (completedCount * 100.0) / orders.size()); @@ -266,10 +280,6 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { // 5. 景区路线订单分布 result.setRouteOrderDistribution(calculateRouteDistribution(orders)); - - // 6. 时间序列数据(日/月/季/年统计) - result.setTimeSeriesData(timeSeriesData); - return result; } @@ -286,29 +296,12 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { /** * 按状态统计订单数量 */ - private long countOrdersByStatus(List orders,Integer orderItemStatus) { + private long countOrdersByStatus(List orders, Integer mainOrderStatus) { if (orders == null) return 0; - // 遍历订单主表,统计包含指定状态子项的订单数量 + // 遍历订单主表,统计主单的状态数量 return orders.stream() - .filter(order -> { - // 获取当前订单的所有子项 - List orderDetails = orderDetailMapper.getOrderDetailsByOrderId(order.getId()); - - // 如果订单没有子项,不统计 - if (orderDetails == null || orderDetails.isEmpty()) { - return false; - } - - // 如果未指定状态,只要有子项就统计 - if (orderItemStatus == null) { - return true; - } - - // 检查是否有子项符合指定状态 - return orderDetails.stream() - .anyMatch(item -> orderItemStatus.equals(item.getOrderItemStatus())); - }) + .filter(order -> mainOrderStatus.equals(order.getMainOrderStatus())) .count(); } @@ -411,9 +404,9 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService { private Map calculateRouteDistribution(List orders) { Map routeDistribution = new HashMap<>(); - // 遍历所有订单,统计各路线的订单数量 + // 遍历所有订单,统计各路线的订单数量,1个订单会包含多个路线 for (OrderMain order : orders) { - Long routeId =0L; // TODO 这里路线可能存在多个 + Long routeId = 0L; // TODO 这里路线可能存在多个 String routeName = cpRouteMapper.getNameById(routeId); if (routeName != null) { routeDistribution.put(routeName, routeDistribution.getOrDefault(routeName, 0L) + 1); diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderMainServiceImpl.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderMainServiceImpl.java index c90c681..ca8e54c 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderMainServiceImpl.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderMainServiceImpl.java @@ -5,6 +5,7 @@ import com.aircraft.modules.order.domain.dto.OrderMainPageQueryDTO; import com.aircraft.modules.order.mapper.OrderMainMapper; import com.aircraft.modules.order.service.IOrderMainService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; @@ -28,4 +29,13 @@ public class OrderMainServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); return list(queryWrapper); } + + @Override + public List queryAllOrders() { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.orderByDesc(OrderMain::getOrderCreateTime); + + // 直接调用 MyBatis-Plus 提供的 baseMapper.selectList 方法 + return baseMapper.selectList(wrapper); + } } diff --git a/aircraft-system/src/main/java/com/aircraft/modules/route/controller/CpRouteController.java b/aircraft-system/src/main/java/com/aircraft/modules/route/controller/CpRouteController.java index 762ff17..18d5de9 100644 --- a/aircraft-system/src/main/java/com/aircraft/modules/route/controller/CpRouteController.java +++ b/aircraft-system/src/main/java/com/aircraft/modules/route/controller/CpRouteController.java @@ -7,11 +7,9 @@ import com.aircraft.modules.system.mapper.UserMapper; import com.aircraft.modules.route.service.CpRouteService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -25,6 +23,7 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.net.URI; import java.time.LocalDateTime; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -197,11 +196,47 @@ public class CpRouteController { @ApiOperation(value = "全部路线") // 调整接口描述 @RequestMapping(value = "all", method = RequestMethod.GET) public ResponseEntity> all(CpRoute example) { // 调整实体类 - QueryWrapper queryWrapper=new QueryWrapper<>(example); + QueryWrapper queryWrapper = new QueryWrapper<>(example); List entitys = entityService.list(queryWrapper); if (null != entitys) { return ResponseEntity.ok(entitys); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } + + @ApiOperation(value = "根据景区获取景区下的所有路线") + @RequestMapping(value = "getByAreaId", method = RequestMethod.GET) + public ResponseEntity> getRouteByEmAreaId( + @ApiParam(value = "景区ID", required = true) + @RequestParam("areaId") Long areaId) { + + try { + // 1. 参数校验 + if (areaId == null) { + LOG.warn("查询景区路线失败:景区ID为空"); + return ResponseEntity.badRequest().build(); + } + + // 2. 构建查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("area_id", areaId) + .eq("del_flag", 0); + + // 3. 查询景区下的所有路线 + List routes = entityService.list(queryWrapper); + + // 4. 返回结果 + if (CollectionUtils.isEmpty(routes)) { + LOG.info("景区ID={}下未找到路线数据", areaId); + return ResponseEntity.ok(Collections.emptyList()); + } + + LOG.info("查询景区ID={}下的路线成功,共找到{}条路线", areaId, routes.size()); + return ResponseEntity.ok(routes); + + } catch (Exception e) { + LOG.error("查询景区路线失败,景区ID={}", areaId, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } } \ No newline at end of file diff --git a/aircraft-system/src/main/resources/mapper/order/OrderDetailMapper.xml b/aircraft-system/src/main/resources/mapper/order/OrderDetailMapper.xml index d56426d..be36b43 100644 --- a/aircraft-system/src/main/resources/mapper/order/OrderDetailMapper.xml +++ b/aircraft-system/src/main/resources/mapper/order/OrderDetailMapper.xml @@ -43,7 +43,7 @@ SELECT id, order_id, device_id, - person_conut, + person_count, operator_id, order_item_status, create_by,