订单状态分析更改

This commit is contained in:
温文静WWW 2025-07-13 18:31:23 +08:00
parent 29b47c6dbc
commit 4fa9c3488e
9 changed files with 119 additions and 44 deletions

View File

@ -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<OrderAnalysisResult<T>> analyzeAllOrders() {
try {
// 1. 获取数据库中所有订单数据
List<OrderMain> allOrders = iOrderMainService.queryAllOrders();
// 2. 校验订单数据
if (CollectionUtils.isEmpty(allOrders)) {
LOG.info("全部订单分析:未找到订单数据");
return ResponseEntity.badRequest().body(null);
}
OrderAnalysisResult<T> 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);

View File

@ -13,6 +13,7 @@ public class OrderAnalysisResult<T> {
private Long noStartOrderCount; //未开始的订单量
private Long inProgressOrderCount; // 进行中的订单量
private Long completedOrderCount; // 完成的订单量
private Long cancelOrderCount;//取消的订单量
private Double completionRate; // 完成的订单率
private PageInfo pageInfo; // 分页信息
private List<?> orderList; // 订单列表

View File

@ -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;
/**
* <p>
* 订单主表 Mapper 接口
@ -14,5 +16,4 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public interface OrderMainMapper extends BaseMapper<OrderMain> {
}

View File

@ -24,4 +24,5 @@ public interface IOrderMainService extends IService<OrderMain> {
*/
List<OrderMain> queryAll(OrderMainPageQueryDTO pageQueryDTO);
List<OrderMain> queryAllOrders();
}

View File

@ -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<List<OrderQuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end);
OrderAnalysisResult<List<OrderYearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end);
<T> OrderAnalysisResult<T> analyzeAllOrders(List<OrderMain> allOrders);
}

View File

@ -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 <T> OrderAnalysisResult<T> analyzeAllOrders(List<OrderMain> allOrders) {
return buildAnalysisOrdersResult(allOrders);
}
// ====================== 通用工具方法 ======================
@ -235,6 +239,14 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
* 构建完整的订单分析结果
*/
private <T> OrderAnalysisResult<T> buildAnalysisResult(List<OrderMain> orders, T timeSeriesData) {
OrderAnalysisResult<T> result = buildAnalysisOrdersResult(orders);
// 6. 时间序列数据///年统计
result.setTimeSeriesData(timeSeriesData);
return result;
}
//处理订单返回结果
private <T> OrderAnalysisResult<T> buildAnalysisOrdersResult(List<OrderMain> orders) {
OrderAnalysisResult<T> 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<OrderMain> orders,Integer orderItemStatus) {
private long countOrdersByStatus(List<OrderMain> orders, Integer mainOrderStatus) {
if (orders == null) return 0;
// 遍历订单主表统计包含指定状态子项的订单数量
// 遍历订单主表统计主单的状态数量
return orders.stream()
.filter(order -> {
// 获取当前订单的所有子项
List<OrderDetail> 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<String, Long> calculateRouteDistribution(List<OrderMain> orders) {
Map<String, Long> 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);

View File

@ -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<OrderMainMapper, OrderMain
LambdaQueryWrapper<OrderMain> queryWrapper = new LambdaQueryWrapper<>();
return list(queryWrapper);
}
@Override
public List<OrderMain> queryAllOrders() {
LambdaQueryWrapper<OrderMain> wrapper = Wrappers.lambdaQuery();
wrapper.orderByDesc(OrderMain::getOrderCreateTime);
// 直接调用 MyBatis-Plus 提供的 baseMapper.selectList 方法
return baseMapper.selectList(wrapper);
}
}

View File

@ -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<List<CpRoute>> all(CpRoute example) { // 调整实体类
QueryWrapper<CpRoute> queryWrapper=new QueryWrapper<>(example);
QueryWrapper<CpRoute> queryWrapper = new QueryWrapper<>(example);
List<CpRoute> 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<List<CpRoute>> getRouteByEmAreaId(
@ApiParam(value = "景区ID", required = true)
@RequestParam("areaId") Long areaId) {
try {
// 1. 参数校验
if (areaId == null) {
LOG.warn("查询景区路线失败景区ID为空");
return ResponseEntity.badRequest().build();
}
// 2. 构建查询条件
QueryWrapper<CpRoute> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("area_id", areaId)
.eq("del_flag", 0);
// 3. 查询景区下的所有路线
List<CpRoute> 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();
}
}
}

View File

@ -43,7 +43,7 @@
SELECT id,
order_id,
device_id,
person_conut,
person_count,
operator_id,
order_item_status,
create_by,