Procházet zdrojové kódy

销售-统计看板

donglang před 1 měsícem
rodič
revize
e709b0aed5

+ 19 - 2
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/SalesWaybillOrderResp.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * @author :chenXiaoFei
@@ -41,13 +42,29 @@ public class SalesWaybillOrderResp implements Serializable {
      * 今日出货量
      */
     @Schema(description = "今日出货量")
-    private Integer todayShipmentWeight;
+    private BigDecimal todayShipmentWeight;
 
     /**
      * 本月出货量
      */
     @Schema(description = "本月出货量")
-    private Integer monthShipmentWeight;
+    private BigDecimal monthShipmentWeight;
+
+    /**
+     * 近7天出货量
+     */
+    @Schema(description = "本月出货量")
+    private List<RecentSevenDaysShipmentVO> recentSevenDaysShipmentVOs;
+
+
+    @Data
+    public static class RecentSevenDaysShipmentVO {
+        @Schema(description = "日期:yyyy-MM-dd")
+        private String date;
+
+        @Schema(description = "当日出货量")
+        private BigDecimal shipmentWeight;
+    }
 
 
 }

+ 8 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtGatekeeperWaybillOrderRepository.java

@@ -42,4 +42,12 @@ public class KwtGatekeeperWaybillOrderRepository extends ServiceImpl<KwtGatekeep
                         .last("limit 1"));
     }
 
+    public List<KwtGatekeeperWaybillOrder> queryGatekeeperWaybillOrderByEntId(Long entId, List<Integer> status) {
+        return list(
+                Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
+                        .eq(KwtGatekeeperWaybillOrder::getEntId, entId)
+                        .in(KwtGatekeeperWaybillOrder::getStatus, status)
+                        .orderByDesc(KwtGatekeeperWaybillOrder::getId));
+    }
+
 }

+ 11 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderSubtaskRepository.java

@@ -10,6 +10,7 @@ import com.sckw.transport.model.KwtWaybillOrderSubtask;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.stereotype.Repository;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -95,4 +96,14 @@ public class KwtWaybillOrderSubtaskRepository extends ServiceImpl<KwtWaybillOrde
                 .in(CollectionUtils.isNotEmpty(billOrderIds),KwtWaybillOrderSubtask::getWOrderId, billOrderIds)
         );
     }
+
+    public List<KwtWaybillOrderSubtask> queryWaybillOrderSubByEntIdAndStatus(Long entId, Integer status, LocalDateTime startTime, LocalDateTime endTime) {
+        return list(Wrappers.<KwtWaybillOrderSubtask>lambdaQuery()
+                .eq(KwtWaybillOrderSubtask::getDelFlag,0)
+                .eq(Objects.nonNull(entId),KwtWaybillOrderSubtask::getEntId,entId)
+                .eq(Objects.nonNull(status),KwtWaybillOrderSubtask::getStatus,status)
+                .ge(Objects.nonNull(startTime), KwtWaybillOrderSubtask::getUpdateTime, startTime)
+                .le(Objects.nonNull(endTime), KwtWaybillOrderSubtask::getUpdateTime, endTime)
+                .orderByDesc(KwtWaybillOrderSubtask::getId));
+    }
 }

+ 155 - 18
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/SalesWaybillOrderService.java

@@ -2,11 +2,17 @@ package com.sckw.transport.service.app;
 
 
 import com.alibaba.fastjson.JSON;
+import com.sckw.core.model.constant.Global;
+import com.sckw.core.model.enums.CarWaybillV1Enum;
+import com.sckw.core.model.enums.GatekeeperStatusEnum;
+import com.sckw.core.utils.CollectionUtils;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.transport.handler.*;
+import com.sckw.transport.model.KwtGatekeeperWaybillOrder;
+import com.sckw.transport.model.KwtWaybillOrderSubtask;
 import com.sckw.transport.model.param.SalesWaybillOrderQueryParam;
 import com.sckw.transport.model.param.SalesWaybillOrderResp;
 import com.sckw.transport.model.param.WaybillOrderReq;
@@ -21,6 +27,14 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author zk
@@ -66,25 +80,12 @@ public class SalesWaybillOrderService {
     private final UnloadingHandler unloadingHandler;
 
     private final KwtWaybillOrderV1Service waybillOrderV1Service;
+    private final KwtGatekeeperWaybillOrderRepository gatekeeperWaybillOrderRepository;
 
     // 注入RedisTemplate用于分布式锁
     @Resource
     private RedisTemplate<String, String> redisTemplate;
 
-    // 分布式锁相关常量
-    private static final String TAKING_ORDER_LOCK_PREFIX = "transport:taking_order:lock:";
-    // 锁超时时间30秒
-    private static final long LOCK_EXPIRE_SECONDS = 30;
-    // 锁等待时间500毫秒
-    private static final long LOCK_WAIT_MILLIS = 500;
-    // 锁重试间隔100毫秒
-    private static final long LOCK_RETRY_INTERVAL = 100;
-
-    //载重任务量浮动吨数
-    private static final BigDecimal TWO_TONS = new BigDecimal("2");
-    //载重任务量计算比例
-    private static final BigDecimal EIGHTY_PERCENT = new BigDecimal("0.8");
-
     /**
      * 查询销售数据
      * @param param
@@ -93,11 +94,19 @@ public class SalesWaybillOrderService {
     public SalesWaybillOrderResp querySalesStatistics(SalesWaybillOrderQueryParam param) {
         log.info("查询销售数据:{}", JSON.toJSONString(param));
         SalesWaybillOrderResp salesResp = new SalesWaybillOrderResp();
-        // 查询执行中订单(物流订单)
-        WaybillOrderReq req = new WaybillOrderReq();
-        req.setEntId(String.valueOf(param.getEntId()));
+        // 1. 计算执行中订单(物流订单)
+        calOngoingLogOrder(param, salesResp);
+
+        // 2.计算今日车次
+        calTodayTruckCount(param, salesResp);
+
+        // 3.计算场内车辆
+        calInsideVehicleCount(param, salesResp);
+
+        // 4.计算今日出货量
+
+        // 5.计算本月出货量
 
-        StatisticsWaybillResp statisticsWaybillResp = waybillOrderV1Service.statisticsWaybillOrder(req);
 
 
         log.info("查询销售数据成功,结果:{}", JSON.toJSONString(salesResp));
@@ -106,4 +115,132 @@ public class SalesWaybillOrderService {
 
     }
 
+    /**
+     *  计算执行中订单
+     * @param param
+     * @param salesResp
+     */
+    private void calOngoingLogOrder(SalesWaybillOrderQueryParam param, SalesWaybillOrderResp salesResp) {
+        WaybillOrderReq req = new WaybillOrderReq();
+        req.setEntId(String.valueOf(param.getEntId()));
+        StatisticsWaybillResp statisticsWaybillResp = waybillOrderV1Service.statisticsWaybillOrder(req);
+        if (statisticsWaybillResp == null) {
+            salesResp.setOngoingLogOrder(Global.NUMERICAL_ZERO);
+        }
+        List<String> targetStatus = List.of("5", "10", "15");
+        List<StatisticsWaybillResp.OrderBillStatusStatistics> orderStatusStatistics = statisticsWaybillResp.getOrderStatusStatistics();
+        int ongoingLogOrder = orderStatusStatistics.stream().filter(Objects::nonNull)
+                .filter(stat -> targetStatus.contains(stat.getOrderStatus()))
+                .mapToInt(s -> {
+                    try {
+                        return Integer.parseInt(s.getOrderNum());
+                    } catch (Exception e) {
+                        return 0;
+                    }
+                })
+                .sum();
+        salesResp.setOngoingLogOrder(ongoingLogOrder);
+    }
+
+    /**
+     *  计算今日车次
+     * @param param
+     * @param salesResp
+     */
+    private void calTodayTruckCount(SalesWaybillOrderQueryParam param, SalesWaybillOrderResp salesResp) {
+        //今日车次
+        LocalDateTime todayStart = LocalDate.now().atStartOfDay();          // 今天 00:00:00
+        LocalDateTime todayEnd = LocalDate.now().atTime(23, 59, 59);
+        List<KwtWaybillOrderSubtask> todayTruckCount = waybillOrderSubtaskRepository
+                .queryWaybillOrderSubByEntIdAndStatus(param.getEntId(), CarWaybillV1Enum.COMPLETED.getCode(), todayStart, todayEnd);
+        if (CollectionUtils.isEmpty(todayTruckCount)) {
+            salesResp.setTodayTruckCount(Global.NUMERICAL_ZERO);
+            salesResp.setTodayShipmentWeight(BigDecimal.ZERO);
+        }
+        //今日车次
+        salesResp.setTodayTruckCount(todayTruckCount.size());
+        //今日出货量
+        BigDecimal todayLoadAmount = todayTruckCount.stream()
+                .filter(sub -> sub.getLoadAmount() != null)
+                .map(KwtWaybillOrderSubtask::getLoadAmount)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        salesResp.setTodayShipmentWeight(todayLoadAmount);
+
+        //本月出货量
+        LocalDateTime monthStart = LocalDate.now().withDayOfMonth(1).atStartOfDay();
+        LocalDateTime monthEnd = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).atTime(23, 59, 59);
+        List<KwtWaybillOrderSubtask> monthShipmentWeight = waybillOrderSubtaskRepository
+                .queryWaybillOrderSubByEntIdAndStatus(param.getEntId(), CarWaybillV1Enum.COMPLETED.getCode(), monthStart, monthEnd);
+        if (CollectionUtils.isEmpty(todayTruckCount)) {
+            salesResp.setMonthShipmentWeight(BigDecimal.ZERO);
+        }
+        //本月出货量
+        BigDecimal monthLoadAmount = todayTruckCount.stream()
+                .filter(sub -> sub.getLoadAmount() != null)
+                .map(KwtWaybillOrderSubtask::getLoadAmount)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        salesResp.setTodayShipmentWeight(monthLoadAmount);
+
+        // 1. 定义时间范围:近7天(包含今天)
+        LocalDate today = LocalDate.now();
+        LocalDateTime sevenDaysStartTime = today.minusDays(6).atStartOfDay(); // 7天前 00:00:00
+        LocalDateTime sevenDaysEndTime = today.atTime(23, 59, 59);                     // 今天 23:59:59
+
+        // 2. 查询数据库:获取近7天的所有已完成子运单数据
+        List<KwtWaybillOrderSubtask> subtaskList = waybillOrderSubtaskRepository
+                .queryWaybillOrderSubByEntIdAndStatus(param.getEntId(), CarWaybillV1Enum.COMPLETED.getCode(), sevenDaysStartTime, sevenDaysEndTime);
+
+        // 3. 内存分组统计:按“日期”聚合求和
+        // 结果格式:Map<"2026-04-23", 100.5>
+        Map<String, BigDecimal> dailyWeightMap = subtaskList.stream()
+                .filter(task -> task.getLoadAmount() != null) // 过滤空值
+                .collect(Collectors.groupingBy(
+                        // 关键:按创建时间的日期部分分组 (yyyy-MM-dd)
+                        task -> java.time.LocalDateTime.ofInstant(task.getCreateTime().toInstant(),
+                                        java.time.ZoneId.systemDefault()).toLocalDate().toString(),
+                        // 求和
+                        Collectors.mapping(KwtWaybillOrderSubtask::getLoadAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))
+                ));
+
+        // 4. 构建前端需要的 VO 列表(按时间顺序,并补全缺失日期的0值)
+        List<SalesWaybillOrderResp.RecentSevenDaysShipmentVO> resultVOs = new ArrayList<>();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        for (int i = 6; i >= 0; i--) {
+            // 倒序循环:从6天前遍历到今天,保证列表是按时间正序排列
+            LocalDate date = today.minusDays(i);
+            String dateStr = date.format(formatter);
+
+            // 从 Map 中获取当天的重量,如果没有数据则默认为 0
+            BigDecimal weight = dailyWeightMap.getOrDefault(dateStr, BigDecimal.ZERO);
+
+            SalesWaybillOrderResp.RecentSevenDaysShipmentVO vo = new SalesWaybillOrderResp.RecentSevenDaysShipmentVO();
+            vo.setDate(dateStr);
+            vo.setShipmentWeight(weight);
+
+            resultVOs.add(vo);
+        }
+        salesResp.setRecentSevenDaysShipmentVOs(resultVOs);
+    }
+
+    /**
+     * 计算场内车辆
+     * @param param
+     * @param salesResp
+     */
+    private void calInsideVehicleCount(SalesWaybillOrderQueryParam param, SalesWaybillOrderResp salesResp) {
+        List<KwtGatekeeperWaybillOrder> kwtGatekeeperWaybillOrders = gatekeeperWaybillOrderRepository
+                .queryGatekeeperWaybillOrderByEntId(param.getEntId(),
+                        List.of(GatekeeperStatusEnum.IN_YARD.getCode(),
+                                GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
+                                GatekeeperStatusEnum.READY_RELEASE.getCode()));
+        if (kwtGatekeeperWaybillOrders.isEmpty()) {
+            salesResp.setInsideVehicleCount(Global.NUMERICAL_ZERO);
+        }
+        salesResp.setInsideVehicleCount(kwtGatekeeperWaybillOrders.size());
+    }
+
+
+
+
 }