无人机使用率+任务执行平均周期等
This commit is contained in:
parent
6bb01e0e27
commit
d673362a77
@ -53,7 +53,7 @@ public class CpTextController {
|
||||
@Autowired
|
||||
private CpTextMapper cpTextMapper;
|
||||
|
||||
// @AnonymousAccess
|
||||
@AnonymousAccess
|
||||
@ApiOperation(value = "分页查询文本内容", notes = "分页查询文本内容")
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
@ApiImplicitParams({
|
||||
|
@ -61,8 +61,6 @@ public class OrderDetailAnalysisController {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("按日范围分析子单任务")
|
||||
@GetMapping("/day")
|
||||
// 额外返回:时间范围内任务列表
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -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;//每日失败数量
|
||||
}
|
||||
|
@ -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;//每月失败数量
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class OrderDetailAnalysisResult<T> {
|
||||
private BigDecimal failedRate; // 任务失败率
|
||||
|
||||
private Double averageTaskCycle; // 平均任务周期
|
||||
private BigDecimal droneUsageRate; // 无人机使用率
|
||||
private BigDecimal droneUsageRate; // 今日无人机使用率
|
||||
|
||||
private List<RouteStat> routeDistribution; // 景区路线统计分布
|
||||
private PageInfo pageInfo; // 分页信息
|
||||
|
@ -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;//每季失败数量
|
||||
}
|
||||
|
@ -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;//每年失败数量
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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<T> analyzeAllOrderDetails(List<OrderDetail> allDetails) {
|
||||
@ -69,30 +69,36 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
|
||||
return buildEmptyResult();
|
||||
}
|
||||
|
||||
// 2. 按日分组统计每日订单量
|
||||
Map<String, Long> dailyCountMap = orders.stream()
|
||||
// 2. 时间范围内总订单量
|
||||
Map<String, Long> 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<DailyStat> dailyStats = new ArrayList<>();
|
||||
LocalDate current = start;
|
||||
// 4.计算每日完成量和失败量
|
||||
Map<String, Long> dailyCompletedMap = calculateDailyStatusCount(orders, STATUS_COMPLETED);
|
||||
Map<String, Long> 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<MonthlyStat> monthlyStats = new ArrayList<>();
|
||||
LocalDate current = start.withDayOfMonth(1); // 从当月第一天开始
|
||||
LocalDate endMonth = end.withDayOfMonth(1); // 结束月份第一天
|
||||
|
||||
Map<String, Long> monthlyCompletedMap = calculateMonthlyStatusCount(orders, STATUS_COMPLETED);
|
||||
Map<String, Long> 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<String, Long> quarterlyCompletedMap = calculateQuarterlyStatusCount(orders, STATUS_COMPLETED);
|
||||
Map<String, Long> 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<YearlyStat> yearlyStats = new ArrayList<>();
|
||||
int startYear = start.getYear();
|
||||
int endYear = end.getYear();
|
||||
|
||||
Map<String, Long> yearlyCompletedMap = calculateYearlyStatusCount(orders, STATUS_COMPLETED);
|
||||
Map<String, Long> 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<OrderDetail> orderQueryWrapper = new QueryWrapper<>();
|
||||
// 筛选今日创建的订单
|
||||
orderQueryWrapper.ge("create_time", todayStart)
|
||||
.lt("create_time", todayEnd);
|
||||
|
||||
List<OrderDetail> todayOrders = orderDetailService.list(orderQueryWrapper);
|
||||
|
||||
Set<Long> usedDroneIds = new HashSet<>();
|
||||
for (OrderDetail order : todayOrders) {
|
||||
Long droneId = order.getDeviceId();
|
||||
if (droneId != null) {
|
||||
usedDroneIds.add(droneId);
|
||||
}
|
||||
}
|
||||
int usedDroneCount = usedDroneIds.size();
|
||||
|
||||
|
||||
// 2. 获取无人机总量
|
||||
QueryWrapper<AircraftDevice> 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<OrderDetail> orderDetails) {
|
||||
//获取任务数
|
||||
@ -307,7 +360,7 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
|
||||
return (double) totalSeconds / (60.0 * completedTaskCount);
|
||||
}
|
||||
|
||||
//计算无人机使用率
|
||||
//计算时间范围内无人机使用率
|
||||
private BigDecimal calculateDroneUsageRate(List<OrderDetail> orderDetails) {
|
||||
// 1. 获取时间范围内订单中出现的无人机数量(去重)
|
||||
Set<Long> usedDroneIds = orderDetails.stream()
|
||||
@ -329,7 +382,7 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
|
||||
}
|
||||
|
||||
/**
|
||||
* 按状态统计任务数量
|
||||
* 按状态统计时间范围内的任务数量
|
||||
*/
|
||||
private long countTasksByStatus(List<OrderDetail> tasks, Integer status) {
|
||||
return tasks.stream()
|
||||
@ -337,6 +390,54 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
|
||||
.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按日期和状态统计每日订单数量
|
||||
*/
|
||||
private Map<String, Long> calculateDailyStatusCount(List<OrderDetail> 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<String, Long> calculateMonthlyStatusCount(List<OrderDetail> 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<String, Long> calculateQuarterlyStatusCount(List<OrderDetail> 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<String, Long> calculateYearlyStatusCount(List<OrderDetail> 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()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算比率(保留两位小数)
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user