Commit f7cd8573fda670e8d4241ed595b659cbcc5c2487

Authored by YunaiV
1 parent a9464080

feat(wms):增加首页的 review

yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/WmsHomeStatisticsController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventorySummaryRespVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderSummaryRespVO;
  6 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderTrendRespVO;
  7 +import cn.iocoder.yudao.module.wms.service.home.WmsHomeStatisticsService;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.Parameter;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import jakarta.annotation.Resource;
  12 +import jakarta.validation.constraints.Max;
  13 +import jakarta.validation.constraints.Min;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RequestParam;
  19 +import org.springframework.web.bind.annotation.RestController;
  20 +
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  24 +
  25 +@Tag(name = "管理后台 - WMS 首页统计")
  26 +@RestController
  27 +@RequestMapping("/wms/home-statistics")
  28 +@Validated
  29 +public class WmsHomeStatisticsController {
  30 +
  31 + @Resource
  32 + private WmsHomeStatisticsService homeStatisticsService;
  33 +
  34 + @GetMapping("/order-summary")
  35 + @Operation(summary = "获得首页单据汇总统计")
  36 + @Parameter(name = "warehouseId", description = "仓库编号", example = "1024")
  37 + @PreAuthorize("@ss.hasPermission('wms:home:query')")
  38 + public CommonResult<List<WmsHomeOrderSummaryRespVO>> getOrderSummary(
  39 + @RequestParam(value = "warehouseId", required = false) Long warehouseId) {
  40 + return success(homeStatisticsService.getOrderSummary(warehouseId));
  41 + }
  42 +
  43 + @GetMapping("/order-trend")
  44 + @Operation(summary = "获得首页单据趋势")
  45 + @Parameter(name = "days", description = "天数", example = "7")
  46 + @PreAuthorize("@ss.hasPermission('wms:home:query')")
  47 + public CommonResult<List<WmsHomeOrderTrendRespVO>> getOrderTrend(
  48 + @RequestParam(value = "days", defaultValue = "7") @Min(1) @Max(90) Integer days,
  49 + @RequestParam(value = "warehouseId", required = false) Long warehouseId) {
  50 + return success(homeStatisticsService.getOrderTrend(days, warehouseId));
  51 + }
  52 +
  53 + @GetMapping("/inventory-summary")
  54 + @Operation(summary = "获得首页库存汇总统计")
  55 + @Parameter(name = "warehouseId", description = "仓库编号", example = "1024")
  56 + @PreAuthorize("@ss.hasPermission('wms:home:query')")
  57 + public CommonResult<WmsHomeInventorySummaryRespVO> getInventorySummary(
  58 + @RequestParam(value = "warehouseId", required = false) Long warehouseId) {
  59 + return success(homeStatisticsService.getInventorySummary(warehouseId));
  60 + }
  61 +
  62 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeInventoryItemRankRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - WMS 首页商品库存排行 Response VO")
  9 +@Data
  10 +public class WmsHomeInventoryItemRankRespVO {
  11 +
  12 + // TODO @AI:改成 id、name 会不会更好?
  13 +
  14 + @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + private Long itemId;
  16 +
  17 + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "A4 复印纸")
  18 + private String itemName;
  19 +
  20 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  21 + private BigDecimal quantity;
  22 +
  23 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeInventorySummaryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - WMS 首页库存汇总统计 Response VO")
  10 +@Data
  11 +public class WmsHomeInventorySummaryRespVO {
  12 +
  13 + // TODO @AI:一次性的 VO ,要不合并到 WmsHomeInventorySummaryRespVO 里?一个叫 ItemRank,一个叫 WarehouseRank?
  14 +
  15 + @Schema(description = "总库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
  16 + private BigDecimal totalQuantity;
  17 +
  18 + @Schema(description = "商品库存占比列表")
  19 + private List<WmsHomeInventoryItemRankRespVO> goodsShareList;
  20 +
  21 + @Schema(description = "仓库库存分布列表")
  22 + private List<WmsHomeInventoryWarehouseRankRespVO> warehouseDistributionList;
  23 +
  24 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeInventoryWarehouseRankRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - WMS 首页仓库库存排行 Response VO")
  9 +@Data
  10 +public class WmsHomeInventoryWarehouseRankRespVO {
  11 +
  12 + // TODO @AI:改成 id、name 会不会更好?
  13 +
  14 + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + private Long warehouseId;
  16 +
  17 + @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海仓")
  18 + private String warehouseName;
  19 +
  20 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  21 + private BigDecimal quantity;
  22 +
  23 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeOrderStatusRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Data;
  6 +import lombok.NoArgsConstructor;
  7 +
  8 +@Schema(description = "管理后台 - WMS 首页单据状态统计 Response VO")
  9 +@Data
  10 +@NoArgsConstructor
  11 +@AllArgsConstructor
  12 +public class WmsHomeOrderStatusRespVO {
  13 +
  14 + @Schema(description = "状态值", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  15 + private Integer status;
  16 +
  17 + // TODO @AI:statusName 前端字段就翻译点?
  18 + @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "草稿")
  19 + private String statusName;
  20 +
  21 + @Schema(description = "单据数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
  22 + private Long count;
  23 +
  24 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeOrderSummaryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "管理后台 - WMS 首页单据汇总统计 Response VO")
  9 +@Data
  10 +public class WmsHomeOrderSummaryRespVO {
  11 +
  12 + // TODO @AI:orderType 缩写成 type?
  13 +
  14 + @Schema(description = "单据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + private Integer orderType;
  16 +
  17 + // TODO @AI:type 改成 dict tag 去翻译?或者字典工具类?
  18 + @Schema(description = "单据类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "入库单")
  19 + private String orderTypeName;
  20 +
  21 + @Schema(description = "单据总数", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
  22 + private Long total;
  23 +
  24 + // TODO @AI:statuses;状态分布;
  25 + @Schema(description = "状态分布")
  26 + private List<WmsHomeOrderStatusRespVO> statusList;
  27 +
  28 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/home/vo/WmsHomeOrderTrendRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - WMS 首页单据趋势 Response VO")
  7 +@Data
  8 +public class WmsHomeOrderTrendRespVO {
  9 +
  10 + // TODO @AI:可以使用 localdatetime?前端按需翻译?无非是 time 是 00 00 00 这样。灵活性更大。
  11 + @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-05-14")
  12 + private String date;
  13 +
  14 + @Schema(description = "入库单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
  15 + private Long receiptCount;
  16 +
  17 + @Schema(description = "出库单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8")
  18 + private Long shipmentCount;
  19 +
  20 + @Schema(description = "移库单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
  21 + private Long movementCount;
  22 +
  23 + @Schema(description = "盘库单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  24 + private Long checkCount;
  25 +
  26 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/home/WmsHomeStatisticsMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.dal.mysql.home;
  2 +
  3 +import org.apache.ibatis.annotations.Mapper;
  4 +import org.apache.ibatis.annotations.Param;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +/**
  12 + * WMS 首页统计 Mapper
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Mapper
  17 +public interface WmsHomeStatisticsMapper {
  18 +
  19 + /**
  20 + * 按单据类型和状态统计单据数量
  21 + *
  22 + * @param warehouseId 仓库编号
  23 + * @return [{ "orderType": 1, "status": 0, "count": 5 }, ...]
  24 + */
  25 + List<Map<String, Object>> selectOrderCountGroupByTypeAndStatus(@Param("warehouseId") Long warehouseId);
  26 +
  27 + /**
  28 + * 按天聚合单据数量
  29 + *
  30 + * @param beginTime >= 开始时间
  31 + * @param endTime < 结束时间
  32 + * @param warehouseId 仓库编号
  33 + * @return [{ "date": "2026-05-14", "orderType": 1, "count": 5 }, ...]
  34 + */
  35 + List<Map<String, Object>> selectDailyOrderTrend(@Param("beginTime") LocalDateTime beginTime,
  36 + @Param("endTime") LocalDateTime endTime,
  37 + @Param("warehouseId") Long warehouseId);
  38 +
  39 + /**
  40 + * 统计库存总数量
  41 + *
  42 + * @param warehouseId 仓库编号
  43 + * @return 库存总数量
  44 + */
  45 + BigDecimal selectInventoryTotalQuantity(@Param("warehouseId") Long warehouseId);
  46 +
  47 + /**
  48 + * 按商品统计库存数量排行
  49 + *
  50 + * @param warehouseId 仓库编号
  51 + * @param limit 数量限制
  52 + * @return [{ "itemId": 1, "itemName": "A4 复印纸", "quantity": 100 }, ...]
  53 + */
  54 + List<Map<String, Object>> selectInventoryItemRank(@Param("warehouseId") Long warehouseId,
  55 + @Param("limit") Integer limit);
  56 +
  57 + /**
  58 + * 按仓库统计库存数量排行
  59 + *
  60 + * @param warehouseId 仓库编号
  61 + * @param limit 数量限制
  62 + * @return [{ "warehouseId": 1, "warehouseName": "上海仓", "quantity": 100 }, ...]
  63 + */
  64 + List<Map<String, Object>> selectInventoryWarehouseRank(@Param("warehouseId") Long warehouseId,
  65 + @Param("limit") Integer limit);
  66 +
  67 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/home/WmsHomeStatisticsService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.home;
  2 +
  3 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventorySummaryRespVO;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderSummaryRespVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderTrendRespVO;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * WMS 首页统计 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface WmsHomeStatisticsService {
  15 +
  16 + /**
  17 + * 获得单据汇总统计
  18 + *
  19 + * @param warehouseId 仓库编号
  20 + * @return 单据汇总统计
  21 + */
  22 + List<WmsHomeOrderSummaryRespVO> getOrderSummary(Long warehouseId);
  23 +
  24 + /**
  25 + * 获得单据趋势
  26 + *
  27 + * @param days 天数
  28 + * @param warehouseId 仓库编号
  29 + * @return 单据趋势
  30 + */
  31 + List<WmsHomeOrderTrendRespVO> getOrderTrend(Integer days, Long warehouseId);
  32 +
  33 + /**
  34 + * 获得库存汇总统计
  35 + *
  36 + * @param warehouseId 仓库编号
  37 + * @return 库存汇总统计
  38 + */
  39 + WmsHomeInventorySummaryRespVO getInventorySummary(Long warehouseId);
  40 +
  41 +}
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/home/WmsHomeStatisticsServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.home;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventoryItemRankRespVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventorySummaryRespVO;
  6 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeInventoryWarehouseRankRespVO;
  7 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderStatusRespVO;
  8 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderSummaryRespVO;
  9 +import cn.iocoder.yudao.module.wms.controller.admin.home.vo.WmsHomeOrderTrendRespVO;
  10 +import cn.iocoder.yudao.module.wms.dal.mysql.home.WmsHomeStatisticsMapper;
  11 +import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum;
  12 +import cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum;
  13 +import jakarta.annotation.Resource;
  14 +import org.springframework.stereotype.Service;
  15 +
  16 +import java.math.BigDecimal;
  17 +import java.time.LocalDate;
  18 +import java.time.LocalDateTime;
  19 +import java.time.format.DateTimeFormatter;
  20 +import java.util.ArrayList;
  21 +import java.util.Collections;
  22 +import java.util.HashMap;
  23 +import java.util.LinkedHashMap;
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +
  27 +/**
  28 + * WMS 首页统计 Service 实现类
  29 + *
  30 + * @author 芋道源码
  31 + */
  32 +@Service
  33 +public class WmsHomeStatisticsServiceImpl implements WmsHomeStatisticsService {
  34 +
  35 + // TODO @AI:8、5、交给前端传递;
  36 + private static final int GOODS_SHARE_LIMIT = 5;
  37 + private static final int WAREHOUSE_DISTRIBUTION_LIMIT = 8;
  38 +
  39 + @Resource
  40 + private WmsHomeStatisticsMapper homeStatisticsMapper;
  41 +
  42 + @Override
  43 + public List<WmsHomeOrderSummaryRespVO> getOrderSummary(Long warehouseId) {
  44 + List<Map<String, Object>> stats = homeStatisticsMapper.selectOrderCountGroupByTypeAndStatus(warehouseId);
  45 + // TODO @AI:convertList 链式调用。
  46 + List<WmsHomeOrderSummaryRespVO> result = new ArrayList<>();
  47 + for (WmsOrderTypeEnum orderTypeEnum : WmsOrderTypeEnum.values()) {
  48 + WmsHomeOrderSummaryRespVO vo = new WmsHomeOrderSummaryRespVO()
  49 + .setOrderType(orderTypeEnum.getType()).setOrderTypeName(orderTypeEnum.getName());
  50 + // TODO @AI:collutils sum 是不是可以?
  51 + long total = 0L;
  52 + List<WmsHomeOrderStatusRespVO> statusList = new ArrayList<>();
  53 + for (WmsOrderStatusEnum statusEnum : WmsOrderStatusEnum.values()) {
  54 + long count = getOrderCount(stats, orderTypeEnum.getType(), statusEnum.getStatus());
  55 + total += count;
  56 + statusList.add(new WmsHomeOrderStatusRespVO(statusEnum.getStatus(), statusEnum.getName(), count));
  57 + }
  58 + vo.setTotal(total).setStatusList(statusList);
  59 + result.add(vo);
  60 + }
  61 + return result;
  62 + }
  63 +
  64 + @Override
  65 + public List<WmsHomeOrderTrendRespVO> getOrderTrend(Integer days, Long warehouseId) {
  66 + // TODO @AI:同上?
  67 + LocalDate endDate = LocalDate.now().plusDays(1);
  68 + LocalDate startDate = endDate.minusDays(days);
  69 + LocalDateTime beginTime = startDate.atStartOfDay();
  70 + LocalDateTime endTime = endDate.atStartOfDay();
  71 +
  72 + List<Map<String, Object>> dbData = homeStatisticsMapper.selectDailyOrderTrend(beginTime, endTime, warehouseId);
  73 + Map<String, Map<Integer, Long>> dateMap = new LinkedHashMap<>();
  74 + for (Map<String, Object> row : dbData) {
  75 + String date = (String) row.get("date");
  76 + Integer orderType = getInteger(row, "orderType");
  77 + Long count = getLong(row, "count");
  78 + dateMap.computeIfAbsent(date, key -> new HashMap<>()).put(orderType, count);
  79 + }
  80 + // TODO @AI:链式调用;
  81 + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  82 + List<WmsHomeOrderTrendRespVO> result = new ArrayList<>();
  83 + for (LocalDate d = startDate; d.isBefore(endDate); d = d.plusDays(1)) {
  84 + String dateStr = d.format(fmt);
  85 + Map<Integer, Long> row = dateMap.getOrDefault(dateStr, Collections.emptyMap());
  86 + WmsHomeOrderTrendRespVO vo = new WmsHomeOrderTrendRespVO();
  87 + vo.setDate(dateStr);
  88 + vo.setReceiptCount(row.getOrDefault(WmsOrderTypeEnum.RECEIPT.getType(), 0L));
  89 + vo.setShipmentCount(row.getOrDefault(WmsOrderTypeEnum.SHIPMENT.getType(), 0L));
  90 + vo.setMovementCount(row.getOrDefault(WmsOrderTypeEnum.MOVEMENT.getType(), 0L));
  91 + vo.setCheckCount(row.getOrDefault(WmsOrderTypeEnum.CHECK.getType(), 0L));
  92 + result.add(vo);
  93 + }
  94 + return result;
  95 + }
  96 +
  97 + @Override
  98 + public WmsHomeInventorySummaryRespVO getInventorySummary(Long warehouseId) {
  99 + // TODO @AI:要不都先查询;然后 set 设置值;
  100 + return new WmsHomeInventorySummaryRespVO()
  101 + .setTotalQuantity(getDecimal(homeStatisticsMapper.selectInventoryTotalQuantity(warehouseId)))
  102 + .setGoodsShareList(buildInventoryItemRankList(homeStatisticsMapper.selectInventoryItemRank(warehouseId, GOODS_SHARE_LIMIT)))
  103 + .setWarehouseDistributionList(buildInventoryWarehouseRankList(homeStatisticsMapper.selectInventoryWarehouseRank(warehouseId, WAREHOUSE_DISTRIBUTION_LIMIT)));
  104 + }
  105 +
  106 + // TODO @AI:这个 ===== 太短了,加长!
  107 + // ========== 工具方法 ==========
  108 +
  109 + private long getOrderCount(List<Map<String, Object>> stats, Integer orderType, Integer status) {
  110 + for (Map<String, Object> stat : stats) {
  111 + if (ObjectUtil.equal(getInteger(stat, "orderType"), orderType)
  112 + && ObjectUtil.equal(getInteger(stat, "status"), status)) {
  113 + return getLong(stat, "count");
  114 + }
  115 + }
  116 + return 0L;
  117 + }
  118 +
  119 + // TODO @AI:convertList;然后链式调用;
  120 + private List<WmsHomeInventoryItemRankRespVO> buildInventoryItemRankList(List<Map<String, Object>> rows) {
  121 + List<WmsHomeInventoryItemRankRespVO> result = new ArrayList<>(rows.size());
  122 + for (Map<String, Object> row : rows) {
  123 + WmsHomeInventoryItemRankRespVO vo = new WmsHomeInventoryItemRankRespVO();
  124 + vo.setItemId(getLong(row, "itemId"));
  125 + vo.setItemName((String) row.get("itemName"));
  126 + vo.setQuantity(getDecimal(row.get("quantity")));
  127 + result.add(vo);
  128 + }
  129 + return result;
  130 + }
  131 +
  132 + // TODO @AI:convertList;然后链式调用;
  133 + private List<WmsHomeInventoryWarehouseRankRespVO> buildInventoryWarehouseRankList(List<Map<String, Object>> rows) {
  134 + List<WmsHomeInventoryWarehouseRankRespVO> result = new ArrayList<>(rows.size());
  135 + for (Map<String, Object> row : rows) {
  136 + WmsHomeInventoryWarehouseRankRespVO vo = new WmsHomeInventoryWarehouseRankRespVO();
  137 + vo.setWarehouseId(getLong(row, "warehouseId"));
  138 + vo.setWarehouseName((String) row.get("warehouseName"));
  139 + vo.setQuantity(getDecimal(row.get("quantity")));
  140 + result.add(vo);
  141 + }
  142 + return result;
  143 + }
  144 +
  145 + // TODO @AI:maputil 直接使用
  146 + private Integer getInteger(Map<String, Object> map, String key) {
  147 + Object value = map.get(key);
  148 + return value == null ? null : ((Number) value).intValue();
  149 + }
  150 +
  151 + // TODO @AI:maputil 直接使用
  152 + private Long getLong(Map<String, Object> map, String key) {
  153 + Object value = map.get(key);
  154 + return value == null ? 0L : ((Number) value).longValue();
  155 + }
  156 +
  157 + // TODO @AI:maputil 直接使用
  158 + private BigDecimal getDecimal(Object value) {
  159 + if (value == null) {
  160 + return BigDecimal.ZERO;
  161 + }
  162 + if (value instanceof BigDecimal) {
  163 + return (BigDecimal) value;
  164 + }
  165 + return new BigDecimal(value.toString());
  166 + }
  167 +
  168 +}
... ...
yudao-module-wms/src/main/resources/mapper/home/WmsHomeStatisticsMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.wms.dal.mysql.home.WmsHomeStatisticsMapper">
  4 +
  5 + <!-- 按单据类型和状态统计单据数量 -->
  6 + <select id="selectOrderCountGroupByTypeAndStatus" resultType="java.util.Map">
  7 + SELECT orderType, status, SUM(count) AS count
  8 + FROM (
  9 + SELECT ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@RECEIPT.type} AS orderType,
  10 + status,
  11 + COUNT(*) AS count
  12 + FROM wms_receipt_order
  13 + WHERE deleted = 0
  14 + <if test="warehouseId != null">
  15 + AND warehouse_id = #{warehouseId}
  16 + </if>
  17 + GROUP BY status
  18 + UNION ALL
  19 + SELECT ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@SHIPMENT.type} AS orderType,
  20 + status,
  21 + COUNT(*) AS count
  22 + FROM wms_shipment_order
  23 + WHERE deleted = 0
  24 + <if test="warehouseId != null">
  25 + AND warehouse_id = #{warehouseId}
  26 + </if>
  27 + GROUP BY status
  28 + UNION ALL
  29 + SELECT ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@MOVEMENT.type} AS orderType,
  30 + status,
  31 + COUNT(*) AS count
  32 + FROM wms_movement_order
  33 + WHERE deleted = 0
  34 + <if test="warehouseId != null">
  35 + AND (source_warehouse_id = #{warehouseId} OR target_warehouse_id = #{warehouseId})
  36 + </if>
  37 + GROUP BY status
  38 + UNION ALL
  39 + SELECT ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@CHECK.type} AS orderType,
  40 + status,
  41 + COUNT(*) AS count
  42 + FROM wms_check_order
  43 + WHERE deleted = 0
  44 + <if test="warehouseId != null">
  45 + AND warehouse_id = #{warehouseId}
  46 + </if>
  47 + GROUP BY status
  48 + ) t
  49 + GROUP BY orderType, status
  50 + ORDER BY orderType, status
  51 + </select>
  52 +
  53 + <!-- 按天聚合单据数量 -->
  54 + <select id="selectDailyOrderTrend" resultType="java.util.Map">
  55 + SELECT date, orderType, SUM(count) AS count
  56 + FROM (
  57 + SELECT DATE_FORMAT(order_time, '%Y-%m-%d') AS date,
  58 + ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@RECEIPT.type} AS orderType,
  59 + COUNT(*) AS count
  60 + FROM wms_receipt_order
  61 + WHERE deleted = 0
  62 + AND order_time &gt;= #{beginTime}
  63 + AND order_time &lt; #{endTime}
  64 + <if test="warehouseId != null">
  65 + AND warehouse_id = #{warehouseId}
  66 + </if>
  67 + GROUP BY DATE_FORMAT(order_time, '%Y-%m-%d')
  68 + UNION ALL
  69 + SELECT DATE_FORMAT(order_time, '%Y-%m-%d') AS date,
  70 + ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@SHIPMENT.type} AS orderType,
  71 + COUNT(*) AS count
  72 + FROM wms_shipment_order
  73 + WHERE deleted = 0
  74 + AND order_time &gt;= #{beginTime}
  75 + AND order_time &lt; #{endTime}
  76 + <if test="warehouseId != null">
  77 + AND warehouse_id = #{warehouseId}
  78 + </if>
  79 + GROUP BY DATE_FORMAT(order_time, '%Y-%m-%d')
  80 + UNION ALL
  81 + SELECT DATE_FORMAT(order_time, '%Y-%m-%d') AS date,
  82 + ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@MOVEMENT.type} AS orderType,
  83 + COUNT(*) AS count
  84 + FROM wms_movement_order
  85 + WHERE deleted = 0
  86 + AND order_time &gt;= #{beginTime}
  87 + AND order_time &lt; #{endTime}
  88 + <if test="warehouseId != null">
  89 + AND (source_warehouse_id = #{warehouseId} OR target_warehouse_id = #{warehouseId})
  90 + </if>
  91 + GROUP BY DATE_FORMAT(order_time, '%Y-%m-%d')
  92 + UNION ALL
  93 + SELECT DATE_FORMAT(order_time, '%Y-%m-%d') AS date,
  94 + ${@cn.iocoder.yudao.module.wms.enums.order.WmsOrderTypeEnum@CHECK.type} AS orderType,
  95 + COUNT(*) AS count
  96 + FROM wms_check_order
  97 + WHERE deleted = 0
  98 + AND order_time &gt;= #{beginTime}
  99 + AND order_time &lt; #{endTime}
  100 + <if test="warehouseId != null">
  101 + AND warehouse_id = #{warehouseId}
  102 + </if>
  103 + GROUP BY DATE_FORMAT(order_time, '%Y-%m-%d')
  104 + ) t
  105 + GROUP BY date, orderType
  106 + ORDER BY date, orderType
  107 + </select>
  108 +
  109 + <!-- 统计库存总数量 -->
  110 + <select id="selectInventoryTotalQuantity" resultType="java.math.BigDecimal">
  111 + SELECT IFNULL(SUM(quantity), 0)
  112 + FROM wms_inventory
  113 + WHERE deleted = 0
  114 + <if test="warehouseId != null">
  115 + AND warehouse_id = #{warehouseId}
  116 + </if>
  117 + </select>
  118 +
  119 + <!-- 按商品统计库存数量排行 -->
  120 + <select id="selectInventoryItemRank" resultType="java.util.Map">
  121 + SELECT item.id AS itemId,
  122 + item.name AS itemName,
  123 + IFNULL(SUM(inventory.quantity), 0) AS quantity
  124 + FROM wms_inventory inventory
  125 + INNER JOIN wms_item_sku sku ON sku.id = inventory.sku_id AND sku.deleted = 0
  126 + INNER JOIN wms_item item ON item.id = sku.item_id AND item.deleted = 0
  127 + WHERE inventory.deleted = 0
  128 + AND inventory.quantity &gt; 0
  129 + <if test="warehouseId != null">
  130 + AND inventory.warehouse_id = #{warehouseId}
  131 + </if>
  132 + GROUP BY item.id, item.name
  133 + ORDER BY quantity DESC, item.id ASC
  134 + LIMIT #{limit}
  135 + </select>
  136 +
  137 + <!-- 按仓库统计库存数量排行 -->
  138 + <select id="selectInventoryWarehouseRank" resultType="java.util.Map">
  139 + SELECT warehouse.id AS warehouseId,
  140 + warehouse.name AS warehouseName,
  141 + IFNULL(SUM(inventory.quantity), 0) AS quantity
  142 + FROM wms_inventory inventory
  143 + INNER JOIN wms_warehouse warehouse ON warehouse.id = inventory.warehouse_id AND warehouse.deleted = 0
  144 + WHERE inventory.deleted = 0
  145 + AND inventory.quantity &gt; 0
  146 + <if test="warehouseId != null">
  147 + AND inventory.warehouse_id = #{warehouseId}
  148 + </if>
  149 + GROUP BY warehouse.id, warehouse.name
  150 + ORDER BY quantity DESC, warehouse.id ASC
  151 + LIMIT #{limit}
  152 + </select>
  153 +
  154 +</mapper>
... ...