From d673362a77d11be7a3578b49be9df8c1b8376033 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: Thu, 17 Jul 2025 23:10:19 +0800
Subject: [PATCH] =?UTF-8?q?=E6=97=A0=E4=BA=BA=E6=9C=BA=E4=BD=BF=E7=94=A8?=
=?UTF-8?q?=E7=8E=87+=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C=E5=B9=B3?=
=?UTF-8?q?=E5=9D=87=E5=91=A8=E6=9C=9F=E7=AD=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../article/controller/CpTextController.java | 2 +-
.../OrderDetailAnalysisController.java | 2 -
.../modules/order/domain/OrderDetail.java | 2 +
.../modules/order/domain/dto/DailyStat.java | 4 +-
.../modules/order/domain/dto/MonthlyStat.java | 4 +-
.../domain/dto/OrderDetailAnalysisResult.java | 2 +-
.../order/domain/dto/QuarterlyStat.java | 4 +-
.../modules/order/domain/dto/YearlyStat.java | 4 +-
.../impl/OrderAnalysisServiceImpl.java | 8 +-
.../impl/OrderDetailAnalysisServiceImpl.java | 145 +++++++++++++++---
10 files changed, 143 insertions(+), 34 deletions(-)
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
index a1a1058..ffe6250 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
@@ -53,7 +53,7 @@ public class CpTextController {
@Autowired
private CpTextMapper cpTextMapper;
-// @AnonymousAccess
+ @AnonymousAccess
@ApiOperation(value = "分页查询文本内容", notes = "分页查询文本内容")
@RequestMapping(method = RequestMethod.GET)
@ApiImplicitParams({
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderDetailAnalysisController.java b/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderDetailAnalysisController.java
index 4e0dc09..d449b77 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderDetailAnalysisController.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/controller/OrderDetailAnalysisController.java
@@ -61,8 +61,6 @@ public class OrderDetailAnalysisController {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
-
-
@ApiOperation("按日范围分析子单任务")
@GetMapping("/day")
// 额外返回:时间范围内任务列表
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/OrderDetail.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/OrderDetail.java
index 7280423..4ff9be1 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/OrderDetail.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/OrderDetail.java
@@ -1,5 +1,6 @@
package com.aircraft.modules.order.domain;
+import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.aircraft.base.BaseEntity;
@@ -8,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
/**
*
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/DailyStat.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/DailyStat.java
index 014005d..9c7b395 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/DailyStat.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/DailyStat.java
@@ -6,5 +6,7 @@ import lombok.Data;
@Data
public class DailyStat {
private String date;
- private Long dailyCount;//每日数量
+ private Long dailyTotalCount;//每日总数量
+ private Long dailyCompletedCount;//每日完成数量
+ private Long dailyFailedCount;//每日失败数量
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/MonthlyStat.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/MonthlyStat.java
index 195b1df..4a5b86e 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/MonthlyStat.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/MonthlyStat.java
@@ -5,5 +5,7 @@ import lombok.Data;
@Data
public class MonthlyStat {
private String month;
- private Long monthlyCount;//每月数量
+ private Long monthlyTotalCount;//每月数量
+ private Long monthlyCompletedCount;//每月完成数量
+ private Long monthlyFailedCount;//每月失败数量
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
index 2e5f584..117949f 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
@@ -19,7 +19,7 @@ public class OrderDetailAnalysisResult {
private BigDecimal failedRate; // 任务失败率
private Double averageTaskCycle; // 平均任务周期
- private BigDecimal droneUsageRate; // 无人机使用率
+ private BigDecimal droneUsageRate; // 今日无人机使用率
private List routeDistribution; // 景区路线统计分布
private PageInfo pageInfo; // 分页信息
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/QuarterlyStat.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/QuarterlyStat.java
index e0a8254..8761da7 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/QuarterlyStat.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/QuarterlyStat.java
@@ -5,5 +5,7 @@ import lombok.Data;
@Data
public class QuarterlyStat {
private String quarter; // 季度标识(如2025-Q1)
- private Long QuarterlyCount; // 每季度数量
+ private Long quarterlyTotalCount; // 每季度数量
+ private Long quarterlyCompletedCount;//每季完成数量
+ private Long quarterlyFailedCount;//每季失败数量
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/YearlyStat.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/YearlyStat.java
index bdfa560..69613dd 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/YearlyStat.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/YearlyStat.java
@@ -5,5 +5,7 @@ import lombok.Data;
@Data
public class YearlyStat {
private String year;
- private Long yearlyCount;
+ private Long yearlyTotalCount;//每年总数量
+ private Long yearlyCompletedCount;//每年完成数量
+ private Long yearlyFailedCount;//每年失败数量
}
\ No newline at end of file
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 3c89502..881338a 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
@@ -88,7 +88,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
String dateStr = current.format(DAY_FORMATTER);
DailyStat stat = new DailyStat();
stat.setDate(dateStr);
- stat.setDailyCount(dailyCountMap.getOrDefault(dateStr, 0L));
+ stat.setDailyTotalCount(dailyCountMap.getOrDefault(dateStr, 0L));
dailyStats.add(stat);
current = current.plusDays(1); // 移至下一天
}
@@ -128,7 +128,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
String monthStr = current.format(MONTH_FORMATTER);
MonthlyStat stat = new MonthlyStat();
stat.setMonth(monthStr);
- stat.setMonthlyCount(monthlyCountMap.getOrDefault(monthStr, 0L));
+ stat.setMonthlyTotalCount(monthlyCountMap.getOrDefault(monthStr, 0L));
monthlyStats.add(stat);
current = current.plusMonths(1); // 移至下一月
}
@@ -175,7 +175,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
QuarterlyStat stat = new QuarterlyStat();
stat.setQuarter(quarterStr);
- stat.setQuarterlyCount(quarterCountMap.getOrDefault(quarterStr, 0L));
+ stat.setQuarterlyTotalCount(quarterCountMap.getOrDefault(quarterStr, 0L));
quarterlyStats.add(stat);
// 移至下一季度第一天
@@ -216,7 +216,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
String yearStr = String.valueOf(year);
YearlyStat stat = new YearlyStat();
stat.setYear(yearStr);
- stat.setYearlyCount(yearCountMap.getOrDefault(yearStr, 0L));
+ stat.setYearlyTotalCount(yearCountMap.getOrDefault(yearStr, 0L));
yearlyStats.add(stat);
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
index df30fba..a59973e 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
@@ -6,6 +6,7 @@ import com.aircraft.modules.order.controller.OrderAnalysisController;
import com.aircraft.modules.order.domain.OrderDetail;
import com.aircraft.modules.order.domain.dto.*;
import com.aircraft.modules.order.mapper.OrderDetailMapper;
+import com.aircraft.modules.order.service.IOrderDetailService;
import com.aircraft.modules.order.service.OrderDetailAnalysisService;
import com.aircraft.modules.route.domain.CpRoute;
import com.aircraft.modules.route.mapper.CpRouteMapper;
@@ -21,10 +22,7 @@ import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
-import java.time.Duration;
-import java.time.LocalDate;
-import java.time.YearMonth;
-import java.time.ZoneId;
+import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.*;
@@ -55,6 +53,8 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
private EmScenicMapper emScenicMapper;
@Autowired
private AircraftDeviceService aircraftDeviceService;
+ @Autowired
+ private IOrderDetailService orderDetailService;
@Override
public OrderDetailAnalysisResult analyzeAllOrderDetails(List allDetails) {
@@ -69,30 +69,36 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
return buildEmptyResult();
}
- // 2. 按日分组统计每日订单量
- Map dailyCountMap = orders.stream()
+ // 2. 时间范围内总订单量
+ Map dailyTotalCountMap = orders.stream()
+ .filter(order -> order.getCreateTime() != null) // 过滤掉创建时间为空的订单
.collect(Collectors.groupingBy(
order -> {
+ // 将订单创建时间转换为yyyy-MM-dd格式的日期字符串
LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- return localDate.format(DAY_FORMATTER); // 按日期字符串分组
+ return localDate.format(DAY_FORMATTER);
},
- Collectors.counting() // 统计每组数量
+ Collectors.counting()
));
- System.out.println(dailyCountMap);
+ System.out.println(dailyTotalCountMap);
// 3. 填充每日统计数据(确保日期连续性,即使某天无订单也显示0)
List dailyStats = new ArrayList<>();
LocalDate current = start;
+ // 4.计算每日完成量和失败量
+ Map dailyCompletedMap = calculateDailyStatusCount(orders, STATUS_COMPLETED);
+ Map dailyFailedMap = calculateDailyStatusCount(orders, STATUS_FAILED);
while (!current.isAfter(end)) {
String dateStr = current.format(DAY_FORMATTER);
DailyStat stat = new DailyStat();
stat.setDate(dateStr);
- stat.setDailyCount(dailyCountMap.getOrDefault(dateStr, 0L));
+ stat.setDailyTotalCount(dailyTotalCountMap.getOrDefault(dateStr, 0L));//每日任务总数量
+ stat.setDailyCompletedCount(dailyCompletedMap.getOrDefault(dateStr, 0L)); //每日完成量
+ stat.setDailyFailedCount(dailyFailedMap.getOrDefault(dateStr, 0L));//每日失败量
dailyStats.add(stat);
current = current.plusDays(1); // 移至下一天
}
-
// 4. 构建并返回完整结果
return buildAnalysisResult(orders, dailyStats);
}
@@ -119,12 +125,15 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
List monthlyStats = new ArrayList<>();
LocalDate current = start.withDayOfMonth(1); // 从当月第一天开始
LocalDate endMonth = end.withDayOfMonth(1); // 结束月份第一天
-
+ Map monthlyCompletedMap = calculateMonthlyStatusCount(orders, STATUS_COMPLETED);
+ Map monthlyFailedMap = calculateMonthlyStatusCount(orders, STATUS_FAILED);
while (!current.isAfter(endMonth)) {
String monthStr = current.format(MONTH_FORMATTER);
MonthlyStat stat = new MonthlyStat();
stat.setMonth(monthStr);
- stat.setMonthlyCount(monthlyCountMap.getOrDefault(monthStr, 0L));
+ stat.setMonthlyTotalCount(monthlyCountMap.getOrDefault(monthStr, 0L));
+ stat.setMonthlyCompletedCount(monthlyCompletedMap.getOrDefault(monthStr, 0L));
+ stat.setMonthlyFailedCount(monthlyFailedMap.getOrDefault(monthStr, 0L));
monthlyStats.add(stat);
current = current.plusMonths(1); // 移至下一月
}
@@ -146,7 +155,7 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
.collect(Collectors.groupingBy(
order -> {
// 将 java.util.Date 转换为 java.time.YearMonth
- YearMonth yearMonth = YearMonth.from(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()));
+ YearMonth yearMonth = YearMonth.from(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
int quarter = (yearMonth.getMonthValue() - 1) / 3 + 1;
return yearMonth.format(YEAR_FORMATTER) + "-Q" + quarter;
},
@@ -159,7 +168,8 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
// 调整至当前季度第一天(如2025-05-10 → 2025-04-01)
currentQuarterStart = currentQuarterStart.minusMonths((currentQuarterStart.getMonthValue() - 1) % 3);
currentQuarterStart = currentQuarterStart.withDayOfMonth(1);
-
+ Map quarterlyCompletedMap = calculateQuarterlyStatusCount(orders, STATUS_COMPLETED);
+ Map quarterlyFailedMap = calculateQuarterlyStatusCount(orders, STATUS_FAILED);
while (!currentQuarterStart.isAfter(end)) {
// 计算当前季度标识(如2025-Q2)
int quarter = (currentQuarterStart.getMonthValue() - 1) / 3 + 1;
@@ -167,7 +177,9 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
QuarterlyStat stat = new QuarterlyStat();
stat.setQuarter(quarterStr);
- stat.setQuarterlyCount(quarterCountMap.getOrDefault(quarterStr, 0L));
+ stat.setQuarterlyTotalCount(quarterCountMap.getOrDefault(quarterStr, 0L));
+ stat.setQuarterlyCompletedCount(quarterlyCompletedMap.getOrDefault(quarterStr, 0L));
+ stat.setQuarterlyFailedCount(quarterlyFailedMap.getOrDefault(quarterStr, 0L));
quarterlyStats.add(stat);
// 移至下一季度第一天
@@ -199,12 +211,15 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
List yearlyStats = new ArrayList<>();
int startYear = start.getYear();
int endYear = end.getYear();
-
+ Map yearlyCompletedMap = calculateYearlyStatusCount(orders, STATUS_COMPLETED);
+ Map yearlyFailedMap = calculateYearlyStatusCount(orders, STATUS_FAILED);
for (int year = startYear; year <= endYear; year++) {
String yearStr = String.valueOf(year);
YearlyStat stat = new YearlyStat();
stat.setYear(yearStr);
- stat.setYearlyCount(yearCountMap.getOrDefault(yearStr, 0L));
+ stat.setYearlyTotalCount(yearCountMap.getOrDefault(yearStr, 0L));
+ stat.setYearlyCompletedCount(yearlyCompletedMap.getOrDefault(yearStr, 0L));
+ stat.setYearlyFailedCount(yearlyFailedMap.getOrDefault(yearStr, 0L));
yearlyStats.add(stat);
}
@@ -268,8 +283,10 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
double averageTaskCycle = calculateAverageTaskCycle(orderDetails);
result.setAverageTaskCycle(averageTaskCycle);
- // 新增: 计算无人机使用率
- BigDecimal droneUsageRate = calculateDroneUsageRate(orderDetails);
+ // 新增: 计算今日无人机使用率
+ BigDecimal droneUsageRate = calculateTodayDroneUsageRate();
+// 时间范围内的无人机使用率
+// BigDecimal droneUsageRate = calculateTodayDroneUsageRate(orderDetails);
result.setDroneUsageRate(droneUsageRate);
// 5. 景区路线订单分布
@@ -286,6 +303,42 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
return result;
}
+ //计算当日无人机使用率
+ private BigDecimal calculateTodayDroneUsageRate() {
+ //1. 获取今日订单中出现的无人机数量(去重)
+ LocalDate today = LocalDate.now();
+ LocalDateTime todayStart = today.atStartOfDay();
+ LocalDateTime todayEnd = today.plusDays(1).atStartOfDay();
+
+ QueryWrapper orderQueryWrapper = new QueryWrapper<>();
+ // 筛选今日创建的订单
+ orderQueryWrapper.ge("create_time", todayStart)
+ .lt("create_time", todayEnd);
+
+ List todayOrders = orderDetailService.list(orderQueryWrapper);
+
+ Set usedDroneIds = new HashSet<>();
+ for (OrderDetail order : todayOrders) {
+ Long droneId = order.getDeviceId();
+ if (droneId != null) {
+ usedDroneIds.add(droneId);
+ }
+ }
+ int usedDroneCount = usedDroneIds.size();
+
+
+ // 2. 获取无人机总量
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ int totalDroneCount = aircraftDeviceService.count(queryWrapper);
+
+ // 3. 计算使用率(保留两位小数)
+ if (totalDroneCount == 0) {
+ return BigDecimal.ZERO;
+ }
+ return BigDecimal.valueOf((double) usedDroneCount / totalDroneCount)
+ .setScale(2, RoundingMode.HALF_UP);
+ }
+
//计算平均任务周期
private double calculateAverageTaskCycle(List orderDetails) {
//获取任务数
@@ -307,7 +360,7 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
return (double) totalSeconds / (60.0 * completedTaskCount);
}
- //计算无人机使用率
+ //计算时间范围内无人机使用率
private BigDecimal calculateDroneUsageRate(List orderDetails) {
// 1. 获取时间范围内订单中出现的无人机数量(去重)
Set usedDroneIds = orderDetails.stream()
@@ -329,7 +382,7 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
}
/**
- * 按状态统计任务数量
+ * 按状态统计时间范围内的任务数量
*/
private long countTasksByStatus(List tasks, Integer status) {
return tasks.stream()
@@ -337,6 +390,54 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
.count();
}
+ /**
+ * 按日期和状态统计每日订单数量
+ */
+ private Map calculateDailyStatusCount(List orderDetails, Integer status) {
+ return orderDetails.stream()
+ .filter(order -> order.getOrderItemStatus().equals(status))
+ .collect(Collectors.groupingBy(
+ order -> order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(DAY_FORMATTER),
+ Collectors.counting()
+ ));
+ }
+
+ /**
+ * 按月份和状态统计每月订单数量
+ */
+ private Map calculateMonthlyStatusCount(List orderDetails, Integer status) {
+ return orderDetails.stream()
+ .filter(order -> order.getOrderItemStatus().equals(status))
+ .collect(Collectors.groupingBy(
+ order -> order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(MONTH_FORMATTER),
+ Collectors.counting()
+ ));
+ }
+
+ /**
+ * 按季节和状态统计每计季节订单数量
+ */
+ private Map calculateQuarterlyStatusCount(List orderDetails, Integer status) {
+ return orderDetails.stream()
+ .filter(order -> order.getOrderItemStatus().equals(status))
+ .collect(Collectors.groupingBy(
+ order -> order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(QUARTER_FORMATTER),
+ Collectors.counting()
+ ));
+ }
+
+ /**
+ * 按年份和状态统计每计年订单数量
+ */
+ private Map calculateYearlyStatusCount(List orderDetails, Integer status) {
+ return orderDetails.stream()
+ .filter(order -> order.getOrderItemStatus().equals(status))
+ .collect(Collectors.groupingBy(
+ order -> order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(YEAR_FORMATTER),
+ Collectors.counting()
+ ));
+ }
+
/**
* 计算比率(保留两位小数)
*/