package cn.iocoder.yudao.module.wms.service.home; import cn.hutool.core.date.DatePattern; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventorySummaryRespVO; import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderStatusRespVO; import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderSummaryRespVO; import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderTrendRespVO; import cn.iocoder.yudao.module.wms.dal.mysql.home.WmsHomeStatisticsMapper; import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum; import cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum; import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.getBigDecimal; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.getDateList; /** * WMS 首页统计 Service 实现类 * * @author 芋道源码 */ @Service public class WmsHomeStatisticsServiceImpl implements WmsHomeStatisticsService { @Resource private WmsHomeStatisticsMapper homeStatisticsMapper; @Resource private WmsWarehouseService warehouseService; @Override public List getOrderSummary(Long warehouseId) { validateWarehouseIfPresent(warehouseId); // 查询单据数量 List> stats = homeStatisticsMapper.selectOrderCountGroupByTypeAndStatus(warehouseId); // 按照单据类型 + 单据状态分组 return convertList(WmsOrderTypeEnum.values(), orderTypeEnum -> { List statuses = convertList(WmsOrderStatusEnum.values(), statusEnum -> new WmsHomeOrderStatusRespVO().setStatus(statusEnum.getStatus()) .setCount(getOrderCount(stats, orderTypeEnum.getType(), statusEnum.getStatus()))); Long total = getSumValue(statuses, WmsHomeOrderStatusRespVO::getCount, Long::sum, 0L); return new WmsHomeOrderSummaryRespVO().setType(orderTypeEnum.getType()).setTotal(total).setStatuses(statuses); }); } @Override public List getOrderTrend(Integer days, Long warehouseId) { validateWarehouseIfPresent(warehouseId); // 统计区间为 [今天 - days + 1, 明天),保证最近 days 天包含今天。 LocalDate endDate = LocalDate.now().plusDays(1); LocalDate startDate = endDate.minusDays(days); LocalDateTime beginTime = startDate.atStartOfDay(); LocalDateTime endTime = endDate.atStartOfDay(); // 查询每天的单据数量 List> dbData = homeStatisticsMapper.selectDailyOrderTrend(beginTime, endTime, warehouseId); Map> dateMap = new LinkedHashMap<>(); for (Map row : dbData) { String date = MapUtil.getStr(row, "date"); Integer orderType = MapUtil.getInt(row, "orderType"); Long count = MapUtil.getLong(row, "count", 0L); dateMap.computeIfAbsent(date, key -> new HashMap<>()).put(orderType, count); } // 构造结果,保证每天都有数据 return convertList(getDateList(startDate, days), d -> { String dateStr = DatePattern.NORM_DATE_FORMATTER.format(d); Map row = dateMap.getOrDefault(dateStr, Collections.emptyMap()); return new WmsHomeOrderTrendRespVO().setTime(d.atStartOfDay()) .setReceiptCount(row.getOrDefault(WmsOrderTypeEnum.RECEIPT.getType(), 0L)) .setShipmentCount(row.getOrDefault(WmsOrderTypeEnum.SHIPMENT.getType(), 0L)) .setMovementCount(row.getOrDefault(WmsOrderTypeEnum.MOVEMENT.getType(), 0L)) .setCheckCount(row.getOrDefault(WmsOrderTypeEnum.CHECK.getType(), 0L)); }); } @Override public WmsHomeInventorySummaryRespVO getInventorySummary(Long warehouseId, Integer goodsLimit, Integer warehouseLimit) { validateWarehouseIfPresent(warehouseId); BigDecimal totalQuantity = ObjectUtil.defaultIfNull(homeStatisticsMapper.selectInventoryTotalQuantity(warehouseId), BigDecimal.ZERO); List> itemRows = homeStatisticsMapper.selectInventoryItemRank(warehouseId, goodsLimit); List> warehouseRows = homeStatisticsMapper.selectInventoryWarehouseRank(warehouseId, warehouseLimit); return new WmsHomeInventorySummaryRespVO().setTotalQuantity(totalQuantity) .setGoodsShareList(buildInventoryItemRankList(itemRows)) .setWarehouseDistributionList(buildInventoryWarehouseRankList(warehouseRows)); } // ==================== 工具方法 ==================== /** * 仓库编号非空时,校验仓库是否存在,避免前端误传任意 id 直接落到 SQL。 */ private void validateWarehouseIfPresent(Long warehouseId) { if (warehouseId != null) { warehouseService.validateWarehouseExists(warehouseId); } } private long getOrderCount(List> stats, Integer orderType, Integer status) { for (Map stat : stats) { if (ObjectUtil.equal(MapUtil.getInt(stat, "orderType"), orderType) && ObjectUtil.equal(MapUtil.getInt(stat, "status"), status)) { return MapUtil.getLong(stat, "count", 0L); } } return 0L; } private List buildInventoryItemRankList(List> rows) { return convertList(rows, row -> new WmsHomeInventorySummaryRespVO.ItemRank() .setId(ObjectUtil.defaultIfNull(MapUtil.getLong(row, "id"), MapUtil.getLong(row, "itemId"))) .setName(ObjectUtil.defaultIfNull(MapUtil.getStr(row, "name"), MapUtil.getStr(row, "itemName"))) .setQuantity(getBigDecimal(row, "quantity", BigDecimal.ZERO))); } private List buildInventoryWarehouseRankList(List> rows) { return convertList(rows, row -> new WmsHomeInventorySummaryRespVO.WarehouseRank() .setId(ObjectUtil.defaultIfNull(MapUtil.getLong(row, "id"), MapUtil.getLong(row, "warehouseId"))) .setName(ObjectUtil.defaultIfNull(MapUtil.getStr(row, "name"), MapUtil.getStr(row, "warehouseName"))) .setQuantity(getBigDecimal(row, "quantity", BigDecimal.ZERO))); } }