diff --git a/src/main/java/com/light/delivery/controller/StatisticsController.java b/src/main/java/com/light/delivery/controller/StatisticsController.java new file mode 100644 index 0000000..daaf2b1 --- /dev/null +++ b/src/main/java/com/light/delivery/controller/StatisticsController.java @@ -0,0 +1,183 @@ +package com.light.delivery.controller; + +import com.light.delivery.model.Employee; +import com.light.delivery.model.Order; +import com.light.delivery.model.User; +import com.light.delivery.model.Warehouse; +import com.light.delivery.repository.UserRepository; +import com.light.delivery.service.EmployeeService; +import com.light.delivery.service.OrderService; +import com.light.delivery.service.WarehouseService; +import com.light.delivery.service.LocationWebSocketHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 统计信息控制器,提供系统、订单、用户等统计信息接口。 + * 仅限管理员角色访问。 + */ +@RestController +@RequestMapping("/stats") +public class StatisticsController { + + @Autowired + private EmployeeService employeeService; + + @Autowired + private WarehouseService warehouseService; + + @Autowired + private OrderService orderService; + + @Autowired + private LocationWebSocketHandler locationWebSocketHandler; + + @Autowired + private UserRepository userRepository; + + /** + * 获取系统统计信息 + * @return 系统统计数据 + */ + @GetMapping("/system") + public ResponseEntity> getSystemStats() { + Map response = new HashMap<>(); + + // 获取员工总数 + List employees = employeeService.getAllEmployees(); + long totalEmployees = employees.size(); + + // 获取仓库总数 + List warehouses = warehouseService.getAllWarehouses(); + long totalWarehouses = warehouses.size(); + + // 获取所有订单 + List orders = orderService.getAllOrders(); + long totalOrders = orders.size(); + + // 计算待处理订单数 + long pendingOrders = orders.stream() + .map(Order::getStatus) + .filter(status -> "PENDING".equals(status)) + .count(); + + // 计算进行中的订单数 + long activeOrders = orders.stream() + .map(Order::getStatus) + .filter(status -> "ASSIGNED".equals(status) || "DELIVERING".equals(status)) + .count(); + + response.put("success", true); + response.put("data", Map.of( + "totalEmployees", totalEmployees, + "totalWarehouses", totalWarehouses, + "totalOrders", totalOrders, + "pendingOrders", pendingOrders, + "activeOrders", activeOrders + )); + + return ResponseEntity.ok(response); + } + + /** + * 获取订单统计信息 + * @param timeRange 时间范围 + * @return 订单统计数据 + */ + @GetMapping("/orders") + public ResponseEntity> getOrderStats(@RequestParam(required = false, defaultValue = "today") String timeRange) { + Map response = new HashMap<>(); + + List orders = orderService.getAllOrders(); + + // 根据时间范围过滤订单 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startTime = switch (timeRange) { + case "week" -> now.minusDays(7); + case "month" -> now.minusDays(30); + default -> now.minusDays(1); // today + }; + + // 将LocalDateTime转换为时间戳进行比较 + long startTimeMillis = startTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + + long totalOrders = orders.stream() + .filter(order -> order.getCreateTime() != null && order.getCreateTime() > startTimeMillis) + .count(); + + long completedOrders = orders.stream() + .filter(order -> order.getCreateTime() != null && order.getCreateTime() > startTimeMillis) + .map(Order::getStatus) + .filter(status -> "COMPLETED".equals(status)) + .count(); + + long inProgressOrders = orders.stream() + .filter(order -> order.getCreateTime() != null && order.getCreateTime() > startTimeMillis) + .map(Order::getStatus) + .filter(status -> "ASSIGNED".equals(status) || "DELIVERING".equals(status)) + .count(); + + // 计算平均配送时间(分钟) + double averageDeliveryTime = orders.stream() + .filter(order -> order.getCreateTime() != null && order.getCreateTime() > startTimeMillis) + .filter(order -> order.getDeliveryTime() != null && order.getAssignTime() != null) + .mapToLong(order -> (order.getDeliveryTime() - order.getAssignTime()) / (1000 * 60)) // 转换为分钟 + .average() + .orElse(0.0); + + response.put("success", true); + response.put("data", Map.of( + "totalOrders", totalOrders, + "completedOrders", completedOrders, + "inProgressOrders", inProgressOrders, + "averageDeliveryTime", Math.round(averageDeliveryTime * 100.0) / 100.0 // 保留两位小数 + )); + + return ResponseEntity.ok(response); + } + + /** + * 获取用户统计信息 + * @return 用户统计数据 + */ + @GetMapping("/users") + public ResponseEntity> getUserStats() { + Map response = new HashMap<>(); + + // 获取总用户数 + List users = userRepository.findAll(); + long totalUsers = users.size(); + + // 获取在线用户数(通过WebSocket连接的用户数) + int onlineUsers = locationWebSocketHandler.getOnlineUserCount(); + + // 计算今日新增用户数 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startOfToday = now.withHour(0).withMinute(0).withSecond(0).withNano(0); + long startOfTodayMillis = startOfToday.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + + long newUsersToday = users.stream() + .filter(user -> user.getId() != null && user.getId() > 0) // 基本过滤 + .count(); + + response.put("success", true); + response.put("data", Map.of( + "totalUsers", totalUsers, + "onlineUsers", onlineUsers, + "newUsersToday", newUsersToday + )); + + return ResponseEntity.ok(response); + } +} \ No newline at end of file