diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/facade/IExecutionInboundRankService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/facade/IExecutionInboundRankService.java new file mode 100644 index 000000000..183035a7e --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/facade/IExecutionInboundRankService.java @@ -0,0 +1,26 @@ +package com.mhd.oms.domain.inboundRank.repository.facade; + +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; + +import java.util.List; + +/** + * 入库排名统计Service接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface IExecutionInboundRankService { + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + List queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO); + + /** + * 商品入库排名合计(不分页) + */ + ExecutionInboundRankTotalPO queryMaterialRankTotal(ExecutionInboundRankDO executionInboundRankDO); +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/mapper/ExecutionInboundRankMapper.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/mapper/ExecutionInboundRankMapper.java new file mode 100644 index 000000000..64654e548 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/mapper/ExecutionInboundRankMapper.java @@ -0,0 +1,26 @@ +package com.mhd.oms.domain.inboundRank.repository.mapper; + +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; + +import java.util.List; + +/** + * 入库排名统计Mapper接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface ExecutionInboundRankMapper { + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + List queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO); + + /** + * 商品入库排名合计(不分页,当前筛选条件全量合计) + */ + ExecutionInboundRankTotalPO queryMaterialRankTotal(ExecutionInboundRankDO executionInboundRankDO); +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/persistence/ExecutionInboundRankImpl.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/persistence/ExecutionInboundRankImpl.java new file mode 100644 index 000000000..fe2f19f1c --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/persistence/ExecutionInboundRankImpl.java @@ -0,0 +1,34 @@ +package com.mhd.oms.domain.inboundRank.repository.persistence; + +import com.mhd.oms.domain.inboundRank.repository.facade.IExecutionInboundRankService; +import com.mhd.oms.domain.inboundRank.repository.mapper.ExecutionInboundRankMapper; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计Service业务层处理 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +public class ExecutionInboundRankImpl implements IExecutionInboundRankService { + + @Autowired + private ExecutionInboundRankMapper executionInboundRankMapper; + + @Override + public List queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO) { + return executionInboundRankMapper.queryMaterialRankList(executionInboundRankDO); + } + + @Override + public ExecutionInboundRankTotalPO queryMaterialRankTotal(ExecutionInboundRankDO executionInboundRankDO) { + return executionInboundRankMapper.queryMaterialRankTotal(executionInboundRankDO); + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundMaterialRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundMaterialRankPO.java new file mode 100644 index 000000000..abcf12539 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundMaterialRankPO.java @@ -0,0 +1,79 @@ +package com.mhd.oms.domain.inboundRank.repository.po; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 入库排名统计PO(一行 = 某仓单内某货品的合计,按件数降序排名) + * + *

字段口径:入仓日期=执行入仓单入仓日期;仓单编号=执行入库单号;客户编号/存货人=入仓单货主; + * 件数/毛重/体积=仓单内该货品明细合计;毛重(吨)=明细总毛重KG/1000; + * 投保总额=货品档案保额(NGWL_TEST_WMS.material_base_info.insure_amount,组内取MAX防多批次明细行重复累加)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "入库排名统计对象", description = "入库排名统计响应对象") +public class ExecutionInboundMaterialRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("仓单编号(执行入库单号)") + @Excel(name = "仓单编号") + private String inOrderNumber; + + @ApiModelProperty("客户编号") + @Excel(name = "客户编号") + private String shipperCode; + + @ApiModelProperty("存货人(客户名称)") + @Excel(name = "存货人") + private String shipperName; + + @ApiModelProperty("商品货号") + @Excel(name = "商品货号") + private String materialCode; + + @ApiModelProperty("货名/商品名称") + @Excel(name = "货名") + private String materialName; + + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unitName; + + @ApiModelProperty("件数(仓单内该货品合计,排名依据)") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("毛重(吨)(仓单内该货品合计,KG/1000)") + @Excel(name = "毛重(吨)") + private BigDecimal grossWeightTon; + + @ApiModelProperty("投保总额(货品档案保额)") + @Excel(name = "投保总额") + private BigDecimal insureAmount; + + @ApiModelProperty("体积(CBM)(仓单内该货品合计)") + @Excel(name = "体积(CBM)") + private BigDecimal totalVolume; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundRankTotalPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundRankTotalPO.java new file mode 100644 index 000000000..d3d1bd88d --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/po/ExecutionInboundRankTotalPO.java @@ -0,0 +1,39 @@ +package com.mhd.oms.domain.inboundRank.repository.po; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 入库排名统计合计PO + * + *

当前筛选条件下不分页的全量合计,随分页列表一起返回 + * (totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "入库排名统计合计对象", description = "入库排名统计合计响应对象") +public class ExecutionInboundRankTotalPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("件数合计") + private BigDecimal totalPieceCount; + + @ApiModelProperty("毛重(吨)合计") + private BigDecimal totalGrossWeightTon; + + @ApiModelProperty("投保总额合计(各仓单+货品行保额之和)") + private BigDecimal totalInsureAmount; + + @ApiModelProperty("体积(CBM)合计") + private BigDecimal totalVolume; + + @ApiModelProperty("仓单数合计") + private Long totalOrderCount; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDO.java new file mode 100644 index 000000000..2004bbc56 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDO.java @@ -0,0 +1,47 @@ +package com.mhd.oms.domain.inboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 入库排名统计查询DO + * + *

topOrganizationId 由服务端按登录用户注入,前端不传

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class ExecutionInboundRankDO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期-开始 yyyy-MM-dd(必填)") + private String warehouseDateStart; + + @ApiModelProperty("入仓日期-结束 yyyy-MM-dd(必填)") + private String warehouseDateEnd; + + @ApiModelProperty("仓单编号/入库单号(模糊)") + private String inOrderNumber; + + @ApiModelProperty("客户编号(模糊)") + private String shipperCode; + + @ApiModelProperty("存货人/客户名称(模糊)") + private String shipperName; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("货名/商品名称(模糊)") + private String materialName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("一级组织表ID(登录用户隔离,非1时注入)") + private Long topOrganizationId; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDTO.java new file mode 100644 index 000000000..3e557dd6d --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/repository/todo/ExecutionInboundRankDTO.java @@ -0,0 +1,44 @@ +package com.mhd.oms.domain.inboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 入库排名统计入参DTO + * + *

数据源为 OMS 执行入库链路(execution_in_material_detail / execution_stock_in_order)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class ExecutionInboundRankDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期-开始 yyyy-MM-dd(必填,按入仓单入仓日期筛选)") + private String warehouseDateStart; + + @ApiModelProperty("入仓日期-结束 yyyy-MM-dd(必填,按入仓单入仓日期筛选)") + private String warehouseDateEnd; + + @ApiModelProperty("仓单编号/入库单号(模糊)") + private String inOrderNumber; + + @ApiModelProperty("客户编号(模糊)") + private String shipperCode; + + @ApiModelProperty("存货人/客户名称(模糊)") + private String shipperName; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("货名/商品名称(模糊)") + private String materialName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankApplicationService.java new file mode 100644 index 000000000..5539189ca --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankApplicationService.java @@ -0,0 +1,69 @@ +package com.mhd.oms.domain.inboundRank.service; + +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计应用服务 + * + *

负责登录用户组织隔离注入、日期区间校验,查询逻辑在 ExecutionInboundRankDomainService → ExecutionInboundRankMapper.xml

+ * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class ExecutionInboundRankApplicationService { + + @Autowired + private ExecutionInboundRankDomainService executionInboundRankDomainService; + + /** + * 分页查询商品入库排名列表(仓单+货品汇总,按件数降序) + */ + public List queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO) { + fillLoginContext(executionInboundRankDO); + return executionInboundRankDomainService.queryMaterialRankList(executionInboundRankDO); + } + + /** + * 商品入库排名合计(当前筛选条件全量,不分页) + */ + public ExecutionInboundRankTotalPO queryMaterialRankTotal(ExecutionInboundRankDO executionInboundRankDO) { + return executionInboundRankDomainService.queryMaterialRankTotal(executionInboundRankDO); + } + + /** + * 导出商品入库排名(不分页全量) + */ + public List exportMaterialRank(ExecutionInboundRankDO executionInboundRankDO) { + fillLoginContext(executionInboundRankDO); + return executionInboundRankDomainService.queryMaterialRankList(executionInboundRankDO); + } + + /** + * 注入登录用户组织隔离,并校验入仓日期区间必填 + */ + private void fillLoginContext(ExecutionInboundRankDO executionInboundRankDO) { + if (StringUtils.isEmpty(executionInboundRankDO.getWarehouseDateStart()) || StringUtils.isEmpty(executionInboundRankDO.getWarehouseDateEnd())) { + throw new ServiceException("请选择统计日期区间"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1) { + executionInboundRankDO.setTopOrganizationId(topOrganizationId); + } + } + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankAssembler.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankAssembler.java new file mode 100644 index 000000000..eb4262b8c --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankAssembler.java @@ -0,0 +1,36 @@ +package com.mhd.oms.domain.inboundRank.service; + +import cn.hutool.core.util.ObjectUtil; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDTO; +import org.springframework.stereotype.Component; + +/** + * 入库排名统计Assembler + * + * @author rcx + * @date 2026-08-31 + */ +@Component +public class ExecutionInboundRankAssembler { + + /** + * 转换实体 + */ + public ExecutionInboundRankDO toDO(ExecutionInboundRankDTO executionInboundRankDTO) { + ExecutionInboundRankDO executionInboundRankDO = new ExecutionInboundRankDO(); + // 拷贝 + BeanUtils.copyProperties(executionInboundRankDTO, executionInboundRankDO, IgnoreNullUtil.getNullPropertyNames(executionInboundRankDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + return executionInboundRankDO; + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankDomainService.java new file mode 100644 index 000000000..1b2c34971 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/inboundRank/service/ExecutionInboundRankDomainService.java @@ -0,0 +1,39 @@ +package com.mhd.oms.domain.inboundRank.service; + +import com.mhd.oms.domain.inboundRank.repository.facade.IExecutionInboundRankService; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计领域服务 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class ExecutionInboundRankDomainService { + + @Autowired + private IExecutionInboundRankService executionInboundRankService; + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + public List queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO) { + return executionInboundRankService.queryMaterialRankList(executionInboundRankDO); + } + + /** + * 商品入库排名合计(不分页) + */ + public ExecutionInboundRankTotalPO queryMaterialRankTotal(ExecutionInboundRankDO executionInboundRankDO) { + return executionInboundRankService.queryMaterialRankTotal(executionInboundRankDO); + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java new file mode 100644 index 000000000..b7a1a0830 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java @@ -0,0 +1,37 @@ +package com.mhd.oms.domain.outboundRank.repository.facade; + +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; + +import java.util.List; + +/** + * 出库排名统计Service接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface IExecutionOutboundRankService { + + /** + * 商品出库排名列表 + */ + List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 线路出库排名列表 + */ + List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 商品出库排名合计(不分页) + */ + ExecutionOutboundRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 线路出库排名合计(不分页) + */ + ExecutionOutboundRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO); +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java new file mode 100644 index 000000000..b6722a546 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java @@ -0,0 +1,37 @@ +package com.mhd.oms.domain.outboundRank.repository.mapper; + +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; + +import java.util.List; + +/** + * 出库排名统计Mapper接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface ExecutionOutboundRankMapper { + + /** + * 商品出库排名列表(按销售量倒序) + */ + List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 线路出库排名列表(按销售量倒序) + */ + List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 商品出库排名合计(不分页,当前筛选条件全量合计) + */ + ExecutionOutboundRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO); + + /** + * 线路出库排名合计(不分页,当前筛选条件全量合计) + */ + ExecutionOutboundRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO); +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java new file mode 100644 index 000000000..3c06f90ab --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java @@ -0,0 +1,45 @@ +package com.mhd.oms.domain.outboundRank.repository.persistence; + +import com.mhd.oms.domain.outboundRank.repository.facade.IExecutionOutboundRankService; +import com.mhd.oms.domain.outboundRank.repository.mapper.ExecutionOutboundRankMapper; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计Service业务层处理 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +public class ExecutionOutboundRankImpl implements IExecutionOutboundRankService { + + @Autowired + private ExecutionOutboundRankMapper executionOutboundRankMapper; + + @Override + public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankMapper.queryMaterialRankList(executionOutboundRankDO); + } + + @Override + public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankMapper.queryLineRankList(executionOutboundRankDO); + } + + @Override + public ExecutionOutboundRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankMapper.queryMaterialRankTotal(executionOutboundRankDO); + } + + @Override + public ExecutionOutboundRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankMapper.queryLineRankTotal(executionOutboundRankDO); + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java new file mode 100644 index 000000000..607e789c6 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java @@ -0,0 +1,45 @@ +package com.mhd.oms.domain.outboundRank.repository.po; + +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 线路出库排名PO + * + *

按日期区间对执行出库单聚合:销售量=SUM(出库数量),交易数=COUNT(DISTINCT 出库单号),金额=SUM(明细总价); + * 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "线路出库排名对象", description = "线路出库排名响应对象") +public class ExecutionOutboundLineRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("线路编码") + @Excel(name = "线路编码") + private String lineCode; + + @ApiModelProperty("线路名称") + @Excel(name = "线路名称") + private String lineName; + + @ApiModelProperty("销售量(出库数量合计)") + @Excel(name = "销售量") + private BigDecimal salesQuantity; + + @ApiModelProperty("交易数(出库单据数)") + @Excel(name = "交易数") + private Long tradeCount; + + @ApiModelProperty("金额") + @Excel(name = "金额") + private BigDecimal amount; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java new file mode 100644 index 000000000..ce1cb867e --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java @@ -0,0 +1,52 @@ +package com.mhd.oms.domain.outboundRank.repository.po; + +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 商品出库排名PO + * + *

按日期区间对执行出库明细聚合:销售量=SUM(出库数量),交易数=COUNT(DISTINCT 出库单号),金额=SUM(明细总价)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "商品出库排名对象", description = "商品出库排名响应对象") +public class ExecutionOutboundMaterialRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("商品货号") + @Excel(name = "商品货号") + private String materialCode; + + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String materialName; + + @ApiModelProperty("规格") + @Excel(name = "规格") + private String specificationModel; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unitName; + + @ApiModelProperty("销售量(出库数量合计)") + @Excel(name = "销售量") + private BigDecimal salesQuantity; + + @ApiModelProperty("交易数(出库单据数)") + @Excel(name = "交易数") + private Long tradeCount; + + @ApiModelProperty("金额") + @Excel(name = "金额") + private BigDecimal amount; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundRankTotalPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundRankTotalPO.java new file mode 100644 index 000000000..7622c3593 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundRankTotalPO.java @@ -0,0 +1,32 @@ +package com.mhd.oms.domain.outboundRank.repository.po; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 出库排名合计PO + * + *

当前筛选条件下不分页的全量合计,随分页列表一起返回(totalSalesQuantity/totalTradeCount/totalAmount)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "出库排名合计对象", description = "出库排名合计响应对象") +public class ExecutionOutboundRankTotalPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("销售量合计") + private BigDecimal totalSalesQuantity; + + @ApiModelProperty("交易数合计(去重出库单数)") + private Long totalTradeCount; + + @ApiModelProperty("金额合计") + private BigDecimal totalAmount; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDO.java new file mode 100644 index 000000000..83e8064ce --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDO.java @@ -0,0 +1,50 @@ +package com.mhd.oms.domain.outboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 出库排名统计查询DO + * + *

topOrganizationId 由服务端按登录用户注入,前端不传

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class ExecutionOutboundRankDO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("出库日期-开始 yyyy-MM-dd(必填)") + private String createTimeStart; + + @ApiModelProperty("出库日期-结束 yyyy-MM-dd(必填)") + private String createTimeEnd; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("商品名称(模糊)") + private String materialName; + + @ApiModelProperty("线路编码(模糊)") + private String lineCode; + + @ApiModelProperty("线路名称(模糊)") + private String lineName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("货主名称(模糊)") + private String shipperName; + + @ApiModelProperty("一级组织表ID(登录用户隔离,非1时注入)") + private Long topOrganizationId; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDTO.java new file mode 100644 index 000000000..9b055286f --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/todo/ExecutionOutboundRankDTO.java @@ -0,0 +1,45 @@ +package com.mhd.oms.domain.outboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 出库排名统计入参DTO + * + *

按日期区间统计商品/线路出库量排名,数据源为 OMS 执行出库链路(execution_out_material_detail / execution_stock_out_order)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class ExecutionOutboundRankDTO { + + @ApiModelProperty("出库日期-开始 yyyy-MM-dd(必填,按执行出库单创建时间统计)") + private String createTimeStart; + + @ApiModelProperty("出库日期-结束 yyyy-MM-dd(必填,按执行出库单创建时间统计)") + private String createTimeEnd; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("商品名称(模糊)") + private String materialName; + + @ApiModelProperty("线路编码(模糊)") + private String lineCode; + + @ApiModelProperty("线路名称(模糊)") + private String lineName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("货主名称(模糊)") + private String shipperName; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java new file mode 100644 index 000000000..ef14d18bc --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java @@ -0,0 +1,93 @@ +package com.mhd.oms.domain.outboundRank.service; + +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计应用服务 + * + *

负责登录用户组织隔离注入、日期区间校验,统计逻辑在 ExecutionOutboundRankDomainService → ExecutionOutboundRankMapper.xml

+ * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class ExecutionOutboundRankApplicationService { + + @Autowired + private ExecutionOutboundRankDomainService executionOutboundRankDomainService; + + /** + * 分页查询商品出库排名列表 + */ + public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + fillLoginContext(executionOutboundRankDO); + return executionOutboundRankDomainService.queryMaterialRankList(executionOutboundRankDO); + } + + /** + * 分页查询线路出库排名列表 + */ + public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + fillLoginContext(executionOutboundRankDO); + return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO); + } + + /** + * 商品出库排名合计(当前筛选条件全量,不分页) + */ + public ExecutionOutboundRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankDomainService.queryMaterialRankTotal(executionOutboundRankDO); + } + + /** + * 线路出库排名合计(当前筛选条件全量,不分页) + */ + public ExecutionOutboundRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankDomainService.queryLineRankTotal(executionOutboundRankDO); + } + + /** + * 导出商品出库排名(不分页全量) + */ + public List exportMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + fillLoginContext(executionOutboundRankDO); + return executionOutboundRankDomainService.queryMaterialRankList(executionOutboundRankDO); + } + + /** + * 导出线路出库排名(不分页全量) + */ + public List exportLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + fillLoginContext(executionOutboundRankDO); + return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO); + } + + /** + * 注入登录用户组织隔离,并校验日期区间必填 + */ + private void fillLoginContext(ExecutionOutboundRankDO executionOutboundRankDO) { + if (StringUtils.isEmpty(executionOutboundRankDO.getCreateTimeStart()) || StringUtils.isEmpty(executionOutboundRankDO.getCreateTimeEnd())) { + throw new ServiceException("请选择统计日期区间"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1) { + executionOutboundRankDO.setTopOrganizationId(topOrganizationId); + } + } + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankAssembler.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankAssembler.java new file mode 100644 index 000000000..88ec8e165 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankAssembler.java @@ -0,0 +1,36 @@ +package com.mhd.oms.domain.outboundRank.service; + +import cn.hutool.core.util.ObjectUtil; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDTO; +import org.springframework.stereotype.Component; + +/** + * 出库排名统计Assembler + * + * @author rcx + * @date 2026-08-31 + */ +@Component +public class ExecutionOutboundRankAssembler { + + /** + * 转换实体 + */ + public ExecutionOutboundRankDO toDO(ExecutionOutboundRankDTO executionOutboundRankDTO) { + ExecutionOutboundRankDO executionOutboundRankDO = new ExecutionOutboundRankDO(); + // 拷贝 + BeanUtils.copyProperties(executionOutboundRankDTO, executionOutboundRankDO, IgnoreNullUtil.getNullPropertyNames(executionOutboundRankDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + return executionOutboundRankDO; + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java new file mode 100644 index 000000000..ce87d4968 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java @@ -0,0 +1,54 @@ +package com.mhd.oms.domain.outboundRank.service; + +import com.mhd.oms.domain.outboundRank.repository.facade.IExecutionOutboundRankService; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计领域服务 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class ExecutionOutboundRankDomainService { + + @Autowired + private IExecutionOutboundRankService executionOutboundRankService; + + /** + * 商品出库排名列表 + */ + public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankService.queryMaterialRankList(executionOutboundRankDO); + } + + /** + * 线路出库排名列表 + */ + public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankService.queryLineRankList(executionOutboundRankDO); + } + + /** + * 商品出库排名合计(不分页) + */ + public ExecutionOutboundRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankService.queryMaterialRankTotal(executionOutboundRankDO); + } + + /** + * 线路出库排名合计(不分页) + */ + public ExecutionOutboundRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) { + return executionOutboundRankService.queryLineRankTotal(executionOutboundRankDO); + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/inboundRank/ExecutionInboundRankApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/inboundRank/ExecutionInboundRankApi.java new file mode 100644 index 000000000..9ff29be10 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/inboundRank/ExecutionInboundRankApi.java @@ -0,0 +1,107 @@ +package com.mhd.oms.interfaces.facade.inboundRank; + +import com.github.pagehelper.PageInfo; +import com.mhd.common.core.constant.HttpStatus; +import com.mhd.common.core.utils.PageUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO; +import com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO; +import com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDTO; +import com.mhd.oms.domain.inboundRank.service.ExecutionInboundRankApplicationService; +import com.mhd.oms.domain.inboundRank.service.ExecutionInboundRankAssembler; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; + +/** + * 入库排名统计Api + * + *

按入仓日期区间筛选商品入库量统计排名。统计口径:入仓日期 + 仅已入库状态(5), + * 明细仅取 level=1 主行;一行 = 某仓单内某货品的合计,按件数降序排名。 + * 字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨)/投保总额/体积(CBM)。 + * 与出库排名(/executionOutboundRankApi)配对,前端用 tab 页区分

+ * + * @author rcx + * @date 2026-08-31 + */ +@RestController +@RequestMapping("/executionInboundRankApi") +@Slf4j +public class ExecutionInboundRankApi { + + @Resource + private ExecutionInboundRankAssembler executionInboundRankAssembler; + + @Autowired + private ExecutionInboundRankApplicationService executionInboundRankApplicationService; + + /** + * 分页查询商品入库排名列表(含合计行) + */ + @ApiOperation("分页查询商品入库排名列表") + @GetMapping("/queryMaterialRankList") + public HashMap queryMaterialRankList(ExecutionInboundRankDTO executionInboundRankDTO) { + //转换实体 + ExecutionInboundRankDO executionInboundRankDO = executionInboundRankAssembler.toDO(executionInboundRankDTO); + startPage(); + List list = executionInboundRankApplicationService.queryMaterialRankList(executionInboundRankDO); + ExecutionInboundRankTotalPO total = executionInboundRankApplicationService.queryMaterialRankTotal(executionInboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 导出商品入库排名Excel + */ + @ApiOperation("导出商品入库排名Excel") + @GetMapping("/exportMaterialRank") + public void exportMaterialRank(HttpServletResponse response, ExecutionInboundRankDTO executionInboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + ExecutionInboundRankDO executionInboundRankDO = executionInboundRankAssembler.toDO(executionInboundRankDTO); + List list = executionInboundRankApplicationService.exportMaterialRank(executionInboundRankDO); + + String fileName = URLEncoder.encode("入库排名统计", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(ExecutionInboundMaterialRankPO.class); + util.exportExcel(response, list, "入库排名统计"); + } + + /** + * 分页结果 + 合计行:data/total/code/msg 之外追加 + * totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount + */ + private HashMap getDataTableWithTotal(List list, ExecutionInboundRankTotalPO total) { + HashMap result = new HashMap<>(); + result.put("data", list); + result.put("total", new PageInfo<>(list).getTotal()); + result.put("code", HttpStatus.SUCCESS); + result.put("msg", "查询成功"); + if (total != null) { + result.put("totalPieceCount", total.getTotalPieceCount()); + result.put("totalGrossWeightTon", total.getTotalGrossWeightTon()); + result.put("totalInsureAmount", total.getTotalInsureAmount()); + result.put("totalVolume", total.getTotalVolume()); + result.put("totalOrderCount", total.getTotalOrderCount()); + } + return result; + } + + /** + * 设置请求分页数据 + */ + protected void startPage() { + PageUtils.startPage(); + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java new file mode 100644 index 000000000..07cb22725 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java @@ -0,0 +1,136 @@ +package com.mhd.oms.interfaces.facade.outboundRank; + +import com.github.pagehelper.PageInfo; +import com.mhd.common.core.constant.HttpStatus; +import com.mhd.common.core.utils.PageUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO; +import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundRankTotalPO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO; +import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDTO; +import com.mhd.oms.domain.outboundRank.service.ExecutionOutboundRankApplicationService; +import com.mhd.oms.domain.outboundRank.service.ExecutionOutboundRankAssembler; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; + +/** + * 出库排名统计Api + * + *

按日期区间筛选,统计商品/线路出库量排名。统计口径:执行出库单创建时间 + 已出库状态(9), + * 明细仅取 level=1 主行;销售量=SUM(出库数量)、交易数=COUNT(DISTINCT 出库单号)、金额=SUM(明细总价)

+ * + * @author rcx + * @date 2026-08-31 + */ +@RestController +@RequestMapping("/executionOutboundRankApi") +@Slf4j +public class ExecutionOutboundRankApi { + + @Resource + private ExecutionOutboundRankAssembler executionOutboundRankAssembler; + + @Autowired + private ExecutionOutboundRankApplicationService executionOutboundRankApplicationService; + + /** + * 分页查询商品出库排名列表(含合计行) + */ + @ApiOperation("分页查询商品出库排名列表") + @GetMapping("/queryMaterialRankList") + public HashMap queryMaterialRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) { + //转换实体 + ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO); + startPage(); + List list = executionOutboundRankApplicationService.queryMaterialRankList(executionOutboundRankDO); + ExecutionOutboundRankTotalPO total = executionOutboundRankApplicationService.queryMaterialRankTotal(executionOutboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 分页查询线路出库排名列表(含合计行) + */ + @ApiOperation("分页查询线路出库排名列表") + @GetMapping("/queryLineRankList") + public HashMap queryLineRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) { + //转换实体 + ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO); + startPage(); + List list = executionOutboundRankApplicationService.queryLineRankList(executionOutboundRankDO); + ExecutionOutboundRankTotalPO total = executionOutboundRankApplicationService.queryLineRankTotal(executionOutboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 导出商品出库排名Excel + */ + @ApiOperation("导出商品出库排名Excel") + @GetMapping("/exportMaterialRank") + public void exportMaterialRank(HttpServletResponse response, ExecutionOutboundRankDTO executionOutboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO); + List list = executionOutboundRankApplicationService.exportMaterialRankList(executionOutboundRankDO); + + String fileName = URLEncoder.encode("商品出库排名", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(ExecutionOutboundMaterialRankPO.class); + util.exportExcel(response, list, "商品出库排名"); + } + + /** + * 导出线路出库排名Excel + */ + @ApiOperation("导出线路出库排名Excel") + @GetMapping("/exportLineRank") + public void exportLineRank(HttpServletResponse response, ExecutionOutboundRankDTO executionOutboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO); + List list = executionOutboundRankApplicationService.exportLineRankList(executionOutboundRankDO); + + String fileName = URLEncoder.encode("线路出库排名", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(ExecutionOutboundLineRankPO.class); + util.exportExcel(response, list, "线路出库排名"); + } + + /** + * 分页结果 + 合计行:data/total/code/msg 之外追加 totalSalesQuantity/totalTradeCount/totalAmount + */ + private HashMap getDataTableWithTotal(List list, ExecutionOutboundRankTotalPO total) { + HashMap result = new HashMap<>(); + result.put("data", list); + result.put("total", new PageInfo<>(list).getTotal()); + result.put("code", HttpStatus.SUCCESS); + result.put("msg", "查询成功"); + if (total != null) { + result.put("totalSalesQuantity", total.getTotalSalesQuantity()); + result.put("totalTradeCount", total.getTotalTradeCount()); + result.put("totalAmount", total.getTotalAmount()); + } + return result; + } + + /** + * 设置请求分页数据 + */ + protected void startPage() { + PageUtils.startPage(); + } +} diff --git a/mhd_oms/src/main/resources/mapper/inboundRank/ExecutionInboundRankMapper.xml b/mhd_oms/src/main/resources/mapper/inboundRank/ExecutionInboundRankMapper.xml new file mode 100644 index 000000000..46c335671 --- /dev/null +++ b/mhd_oms/src/main/resources/mapper/inboundRank/ExecutionInboundRankMapper.xml @@ -0,0 +1,102 @@ + + + + + + + a.del_flag = 1 + and a.level = 1 + and b.del_flag = 1 + and b.status = 5 + + and b.top_organization_id = #{topOrganizationId} + + + and b.warehouse_name like concat('%', #{warehouseName}, '%') + + + and b.in_order_number like concat('%', #{inOrderNumber}, '%') + + + and b.shipper_code like concat('%', #{shipperCode}, '%') + + + and b.shipper_name like concat('%', #{shipperName}, '%') + + + and a.material_code like concat('%', #{materialCode}, '%') + + + and a.material_name like concat('%', #{materialName}, '%') + + + and date_format(b.warehouse_date,'%Y-%m-%d') >= #{warehouseDateStart} + + + and date_format(b.warehouse_date,'%Y-%m-%d') <= #{warehouseDateEnd} + + + + + from execution_in_material_detail a + join execution_stock_in_order b on a.in_order_number = b.in_order_number and b.del_flag = 1 + left join NGWL_TEST_WMS.material_base_info c on a.material_base_info_id = c.material_base_info_id + + + + + + + + diff --git a/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml b/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml new file mode 100644 index 000000000..77fccdc12 --- /dev/null +++ b/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml @@ -0,0 +1,124 @@ + + + + + + + a.del_flag = 1 + and a.level = 1 + and b.del_flag = 1 + and b.status = 9 + + and b.top_organization_id = #{topOrganizationId} + + + and b.warehouse_name like concat('%', #{warehouseName}, '%') + + + and b.customer_name like concat('%', #{customerName}, '%') + + + and b.shipper_name like concat('%', #{shipperName}, '%') + + + and b.line_code like concat('%', #{lineCode}, '%') + + + and b.line_name like concat('%', #{lineName}, '%') + + + and date_format(b.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(b.create_time,'%Y-%m-%d') <= #{createTimeEnd} + + + + + from execution_out_material_detail a + join execution_stock_out_order b on a.out_order_number = b.out_order_number and b.del_flag = 1 + + + + + + + + + + + + + + diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/inboundRank/InboundRankApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/inboundRank/InboundRankApplicationService.java new file mode 100644 index 000000000..c5a18f4ff --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/inboundRank/InboundRankApplicationService.java @@ -0,0 +1,76 @@ +package com.mhd.wms.application.service.inboundRank; + +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO; +import com.mhd.system.api.domain.cache.SystemServiceCacheUtil; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; +import com.mhd.wms.domain.inboundRank.service.InboundRankDomainService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计应用服务 + * + *

负责登录用户组织隔离注入、日期区间校验,查询逻辑在 InboundRankDomainService → InboundRankMapper.xml

+ * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class InboundRankApplicationService { + + @Autowired + private InboundRankDomainService inboundRankDomainService; + + /** + * 分页查询商品入库排名列表(仓单+货品汇总,按件数降序) + */ + public List queryMaterialRankList(InboundRankDO inboundRankDO) { + fillLoginContext(inboundRankDO); + return inboundRankDomainService.queryMaterialRankList(inboundRankDO); + } + + /** + * 商品入库排名合计(当前筛选条件全量,不分页) + */ + public InboundRankTotalPO queryMaterialRankTotal(InboundRankDO inboundRankDO) { + return inboundRankDomainService.queryMaterialRankTotal(inboundRankDO); + } + + /** + * 导出商品入库排名(不分页全量) + */ + public List exportMaterialRank(InboundRankDO inboundRankDO) { + fillLoginContext(inboundRankDO); + return inboundRankDomainService.queryMaterialRankList(inboundRankDO); + } + + /** + * 注入登录用户组织隔离与关联仓库,并校验入仓日期区间必填 + */ + private void fillLoginContext(InboundRankDO inboundRankDO) { + if (StringUtils.isEmpty(inboundRankDO.getWarehouseDateStart()) || StringUtils.isEmpty(inboundRankDO.getWarehouseDateEnd())) { + throw new ServiceException("请选择统计日期区间"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1) { + inboundRankDO.setTopOrganizationId(topOrganizationId); + } + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null && associationWarehouseCacheDO.getWarehouseId() != null) { + inboundRankDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + } + } + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java new file mode 100644 index 000000000..3f6d4d267 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java @@ -0,0 +1,100 @@ +package com.mhd.wms.application.service.outboundRank; + +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO; +import com.mhd.system.api.domain.cache.SystemServiceCacheUtil; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; +import com.mhd.wms.domain.outboundRank.service.OutboundRankDomainService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计应用服务 + * + *

负责登录用户组织隔离注入、日期区间校验,统计逻辑在 OutboundRankDomainService → OutboundRankMapper.xml

+ * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class OutboundRankApplicationService { + + @Autowired + private OutboundRankDomainService outboundRankDomainService; + + /** + * 分页查询商品出库排名列表 + */ + public List queryMaterialRankList(OutboundRankDO outboundRankDO) { + fillLoginContext(outboundRankDO); + return outboundRankDomainService.queryMaterialRankList(outboundRankDO); + } + + /** + * 分页查询线路出库排名列表 + */ + public List queryLineRankList(OutboundRankDO outboundRankDO) { + fillLoginContext(outboundRankDO); + return outboundRankDomainService.queryLineRankList(outboundRankDO); + } + + /** + * 商品出库排名合计(当前筛选条件全量,不分页) + */ + public OutboundRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankDomainService.queryMaterialRankTotal(outboundRankDO); + } + + /** + * 线路出库排名合计(当前筛选条件全量,不分页) + */ + public OutboundRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankDomainService.queryLineRankTotal(outboundRankDO); + } + + /** + * 导出商品出库排名(不分页全量) + */ + public List exportMaterialRankList(OutboundRankDO outboundRankDO) { + fillLoginContext(outboundRankDO); + return outboundRankDomainService.queryMaterialRankList(outboundRankDO); + } + + /** + * 导出线路出库排名(不分页全量) + */ + public List exportLineRankList(OutboundRankDO outboundRankDO) { + fillLoginContext(outboundRankDO); + return outboundRankDomainService.queryLineRankList(outboundRankDO); + } + + /** + * 注入登录用户组织隔离与关联仓库,并校验日期区间必填 + */ + private void fillLoginContext(OutboundRankDO outboundRankDO) { + if (StringUtils.isEmpty(outboundRankDO.getCreateTimeStart()) || StringUtils.isEmpty(outboundRankDO.getCreateTimeEnd())) { + throw new ServiceException("请选择统计日期区间"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1) { + outboundRankDO.setTopOrganizationId(topOrganizationId); + } + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null && associationWarehouseCacheDO.getWarehouseId() != null) { + outboundRankDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + } + } + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/facade/IInboundRankService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/facade/IInboundRankService.java new file mode 100644 index 000000000..9559e2d5f --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/facade/IInboundRankService.java @@ -0,0 +1,26 @@ +package com.mhd.wms.domain.inboundRank.repository.facade; + +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; + +import java.util.List; + +/** + * 入库排名统计Service接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface IInboundRankService { + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + List queryMaterialRankList(InboundRankDO inboundRankDO); + + /** + * 商品入库排名合计(不分页) + */ + InboundRankTotalPO queryMaterialRankTotal(InboundRankDO inboundRankDO); +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/mapper/InboundRankMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/mapper/InboundRankMapper.java new file mode 100644 index 000000000..5c95d09fa --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/mapper/InboundRankMapper.java @@ -0,0 +1,26 @@ +package com.mhd.wms.domain.inboundRank.repository.mapper; + +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; + +import java.util.List; + +/** + * 入库排名统计Mapper接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface InboundRankMapper { + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + List queryMaterialRankList(InboundRankDO inboundRankDO); + + /** + * 商品入库排名合计(不分页,当前筛选条件全量合计) + */ + InboundRankTotalPO queryMaterialRankTotal(InboundRankDO inboundRankDO); +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/persistence/InboundRankImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/persistence/InboundRankImpl.java new file mode 100644 index 000000000..519b7cc13 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/persistence/InboundRankImpl.java @@ -0,0 +1,34 @@ +package com.mhd.wms.domain.inboundRank.repository.persistence; + +import com.mhd.wms.domain.inboundRank.repository.facade.IInboundRankService; +import com.mhd.wms.domain.inboundRank.repository.mapper.InboundRankMapper; +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计Service业务层处理 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +public class InboundRankImpl implements IInboundRankService { + + @Autowired + private InboundRankMapper inboundRankMapper; + + @Override + public List queryMaterialRankList(InboundRankDO inboundRankDO) { + return inboundRankMapper.queryMaterialRankList(inboundRankDO); + } + + @Override + public InboundRankTotalPO queryMaterialRankTotal(InboundRankDO inboundRankDO) { + return inboundRankMapper.queryMaterialRankTotal(inboundRankDO); + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundMaterialRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundMaterialRankPO.java new file mode 100644 index 000000000..03567787a --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundMaterialRankPO.java @@ -0,0 +1,79 @@ +package com.mhd.wms.domain.inboundRank.repository.po; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 入库排名统计PO(一行 = 某仓单内某货品的合计,按件数降序排名) + * + *

字段口径:入仓日期=入仓单入仓日期;仓单编号=入库单号;客户编号/存货人=入仓单货主; + * 件数/毛重/体积=仓单内该货品明细合计;毛重(吨)=明细总毛重KG/1000; + * 投保总额=货品档案保额(material_base_info.insure_amount,组内取MAX防多批次明细行重复累加)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "入库排名统计对象", description = "入库排名统计响应对象") +public class InboundMaterialRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("仓单编号(入库单号)") + @Excel(name = "仓单编号") + private String inOrderNumber; + + @ApiModelProperty("客户编号") + @Excel(name = "客户编号") + private String shipperCode; + + @ApiModelProperty("存货人(客户名称)") + @Excel(name = "存货人") + private String shipperName; + + @ApiModelProperty("商品货号") + @Excel(name = "商品货号") + private String materialCode; + + @ApiModelProperty("货名/商品名称") + @Excel(name = "货名") + private String materialName; + + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unitName; + + @ApiModelProperty("件数(仓单内该货品合计,排名依据)") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("毛重(吨)(仓单内该货品合计,KG/1000)") + @Excel(name = "毛重(吨)") + private BigDecimal grossWeightTon; + + @ApiModelProperty("投保总额(货品档案保额)") + @Excel(name = "投保总额") + private BigDecimal insureAmount; + + @ApiModelProperty("体积(CBM)(仓单内该货品合计)") + @Excel(name = "体积(CBM)") + private BigDecimal totalVolume; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundRankTotalPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundRankTotalPO.java new file mode 100644 index 000000000..551bf25d4 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/po/InboundRankTotalPO.java @@ -0,0 +1,39 @@ +package com.mhd.wms.domain.inboundRank.repository.po; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 入库排名统计合计PO + * + *

当前筛选条件下不分页的全量合计,随分页列表一起返回 + * (totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "入库排名统计合计对象", description = "入库排名统计合计响应对象") +public class InboundRankTotalPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("件数合计") + private BigDecimal totalPieceCount; + + @ApiModelProperty("毛重(吨)合计") + private BigDecimal totalGrossWeightTon; + + @ApiModelProperty("投保总额合计(各仓单+货品行保额之和)") + private BigDecimal totalInsureAmount; + + @ApiModelProperty("体积(CBM)合计") + private BigDecimal totalVolume; + + @ApiModelProperty("仓单数合计") + private Long totalOrderCount; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/todo/InboundRankDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/todo/InboundRankDO.java new file mode 100644 index 000000000..1cc725242 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/repository/todo/InboundRankDO.java @@ -0,0 +1,50 @@ +package com.mhd.wms.domain.inboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 入库排名统计查询DO + * + *

topOrganizationId / warehouseId 由服务端按登录用户注入,前端不传

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class InboundRankDO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期-开始 yyyy-MM-dd(必填)") + private String warehouseDateStart; + + @ApiModelProperty("入仓日期-结束 yyyy-MM-dd(必填)") + private String warehouseDateEnd; + + @ApiModelProperty("仓单编号/入库单号(模糊)") + private String inOrderNumber; + + @ApiModelProperty("客户编号(模糊)") + private String shipperCode; + + @ApiModelProperty("存货人/客户名称(模糊)") + private String shipperName; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("货名/商品名称(模糊)") + private String materialName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("一级组织表ID(登录用户隔离,非1时注入)") + private Long topOrganizationId; + + @ApiModelProperty("仓库id(按用户关联仓库注入)") + private Long warehouseId; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/service/InboundRankDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/service/InboundRankDomainService.java new file mode 100644 index 000000000..53e948b61 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inboundRank/service/InboundRankDomainService.java @@ -0,0 +1,39 @@ +package com.mhd.wms.domain.inboundRank.service; + +import com.mhd.wms.domain.inboundRank.repository.facade.IInboundRankService; +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 入库排名统计领域服务 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class InboundRankDomainService { + + @Autowired + private IInboundRankService inboundRankService; + + /** + * 商品入库排名列表(仓单+货品汇总,按件数降序) + */ + public List queryMaterialRankList(InboundRankDO inboundRankDO) { + return inboundRankService.queryMaterialRankList(inboundRankDO); + } + + /** + * 商品入库排名合计(不分页) + */ + public InboundRankTotalPO queryMaterialRankTotal(InboundRankDO inboundRankDO) { + return inboundRankService.queryMaterialRankTotal(inboundRankDO); + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java new file mode 100644 index 000000000..81981ab4b --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java @@ -0,0 +1,37 @@ +package com.mhd.wms.domain.outboundRank.repository.facade; + +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; + +import java.util.List; + +/** + * 出库排名统计Service接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface IOutboundRankService { + + /** + * 商品出库排名列表 + */ + List queryMaterialRankList(OutboundRankDO outboundRankDO); + + /** + * 线路出库排名列表 + */ + List queryLineRankList(OutboundRankDO outboundRankDO); + + /** + * 商品出库排名合计(不分页) + */ + OutboundRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO); + + /** + * 线路出库排名合计(不分页) + */ + OutboundRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO); +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java new file mode 100644 index 000000000..40f17acc2 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java @@ -0,0 +1,37 @@ +package com.mhd.wms.domain.outboundRank.repository.mapper; + +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; + +import java.util.List; + +/** + * 出库排名统计Mapper接口 + * + * @author rcx + * @date 2026-08-31 + */ +public interface OutboundRankMapper { + + /** + * 商品出库排名列表(按销售量倒序) + */ + List queryMaterialRankList(OutboundRankDO outboundRankDO); + + /** + * 线路出库排名列表(按销售量倒序) + */ + List queryLineRankList(OutboundRankDO outboundRankDO); + + /** + * 商品出库排名合计(不分页,当前筛选条件全量合计) + */ + OutboundRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO); + + /** + * 线路出库排名合计(不分页,当前筛选条件全量合计) + */ + OutboundRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO); +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java new file mode 100644 index 000000000..0acf88572 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java @@ -0,0 +1,45 @@ +package com.mhd.wms.domain.outboundRank.repository.persistence; + +import com.mhd.wms.domain.outboundRank.repository.facade.IOutboundRankService; +import com.mhd.wms.domain.outboundRank.repository.mapper.OutboundRankMapper; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计Service业务层处理 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +public class OutboundRankImpl implements IOutboundRankService { + + @Autowired + private OutboundRankMapper outboundRankMapper; + + @Override + public List queryMaterialRankList(OutboundRankDO outboundRankDO) { + return outboundRankMapper.queryMaterialRankList(outboundRankDO); + } + + @Override + public List queryLineRankList(OutboundRankDO outboundRankDO) { + return outboundRankMapper.queryLineRankList(outboundRankDO); + } + + @Override + public OutboundRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankMapper.queryMaterialRankTotal(outboundRankDO); + } + + @Override + public OutboundRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankMapper.queryLineRankTotal(outboundRankDO); + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java new file mode 100644 index 000000000..7f5c05c3c --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java @@ -0,0 +1,45 @@ +package com.mhd.wms.domain.outboundRank.repository.po; + +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 线路出库排名PO + * + *

按日期区间对出库单聚合:销售量=SUM(出库数量),交易数=COUNT(DISTINCT 出库单号),金额=SUM(明细总价); + * 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "线路出库排名对象", description = "线路出库排名响应对象") +public class OutboundLineRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("线路编码") + @Excel(name = "线路编码") + private String lineCode; + + @ApiModelProperty("线路名称") + @Excel(name = "线路名称") + private String lineName; + + @ApiModelProperty("销售量(出库数量合计)") + @Excel(name = "销售量") + private BigDecimal salesQuantity; + + @ApiModelProperty("交易数(出库单据数)") + @Excel(name = "交易数") + private Long tradeCount; + + @ApiModelProperty("金额") + @Excel(name = "金额") + private BigDecimal amount; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java new file mode 100644 index 000000000..9725d50ab --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java @@ -0,0 +1,52 @@ +package com.mhd.wms.domain.outboundRank.repository.po; + +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 商品出库排名PO + * + *

按日期区间对出库明细聚合:销售量=SUM(出库数量),交易数=COUNT(DISTINCT 出库单号),金额=SUM(明细总价)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "商品出库排名对象", description = "商品出库排名响应对象") +public class OutboundMaterialRankPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("商品货号") + @Excel(name = "商品货号") + private String materialCode; + + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String materialName; + + @ApiModelProperty("规格") + @Excel(name = "规格") + private String specificationModel; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unitName; + + @ApiModelProperty("销售量(出库数量合计)") + @Excel(name = "销售量") + private BigDecimal salesQuantity; + + @ApiModelProperty("交易数(出库单据数)") + @Excel(name = "交易数") + private Long tradeCount; + + @ApiModelProperty("金额") + @Excel(name = "金额") + private BigDecimal amount; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundRankTotalPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundRankTotalPO.java new file mode 100644 index 000000000..ea0e9ace9 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundRankTotalPO.java @@ -0,0 +1,32 @@ +package com.mhd.wms.domain.outboundRank.repository.po; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 出库排名合计PO + * + *

当前筛选条件下不分页的全量合计,随分页列表一起返回(totalSalesQuantity/totalTradeCount/totalAmount)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +@ApiModel(value = "出库排名合计对象", description = "出库排名合计响应对象") +public class OutboundRankTotalPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("销售量合计") + private BigDecimal totalSalesQuantity; + + @ApiModelProperty("交易数合计(去重出库单数)") + private Long totalTradeCount; + + @ApiModelProperty("金额合计") + private BigDecimal totalAmount; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/todo/OutboundRankDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/todo/OutboundRankDO.java new file mode 100644 index 000000000..c38c77230 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/todo/OutboundRankDO.java @@ -0,0 +1,53 @@ +package com.mhd.wms.domain.outboundRank.repository.todo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 出库排名统计查询DO + * + *

topOrganizationId / warehouseId 由服务端按登录用户注入,前端不传

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class OutboundRankDO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("出库日期-开始 yyyy-MM-dd(必填)") + private String createTimeStart; + + @ApiModelProperty("出库日期-结束 yyyy-MM-dd(必填)") + private String createTimeEnd; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("商品名称(模糊)") + private String materialName; + + @ApiModelProperty("线路编码(模糊)") + private String lineCode; + + @ApiModelProperty("线路名称(模糊)") + private String lineName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("货主名称(模糊)") + private String shipperName; + + @ApiModelProperty("一级组织表ID(登录用户隔离,非1时注入)") + private Long topOrganizationId; + + @ApiModelProperty("仓库id(按用户关联仓库注入)") + private Long warehouseId; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java new file mode 100644 index 000000000..1d2fe84c2 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java @@ -0,0 +1,54 @@ +package com.mhd.wms.domain.outboundRank.service; + +import com.mhd.wms.domain.outboundRank.repository.facade.IOutboundRankService; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 出库排名统计领域服务 + * + * @author rcx + * @date 2026-08-31 + */ +@Service +@Slf4j +public class OutboundRankDomainService { + + @Autowired + private IOutboundRankService outboundRankService; + + /** + * 商品出库排名列表 + */ + public List queryMaterialRankList(OutboundRankDO outboundRankDO) { + return outboundRankService.queryMaterialRankList(outboundRankDO); + } + + /** + * 线路出库排名列表 + */ + public List queryLineRankList(OutboundRankDO outboundRankDO) { + return outboundRankService.queryLineRankList(outboundRankDO); + } + + /** + * 商品出库排名合计(不分页) + */ + public OutboundRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankService.queryMaterialRankTotal(outboundRankDO); + } + + /** + * 线路出库排名合计(不分页) + */ + public OutboundRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) { + return outboundRankService.queryLineRankTotal(outboundRankDO); + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/inboundRank/InboundRankAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/inboundRank/InboundRankAssembler.java new file mode 100644 index 000000000..f884e0715 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/inboundRank/InboundRankAssembler.java @@ -0,0 +1,36 @@ +package com.mhd.wms.interfaces.assember.inboundRank; + +import cn.hutool.core.util.ObjectUtil; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; +import com.mhd.wms.interfaces.dto.inboundRank.InboundRankDTO; +import org.springframework.stereotype.Component; + +/** + * 入库排名统计Assembler + * + * @author rcx + * @date 2026-08-31 + */ +@Component +public class InboundRankAssembler { + + /** + * 转换实体 + */ + public InboundRankDO toDO(InboundRankDTO inboundRankDTO) { + InboundRankDO inboundRankDO = new InboundRankDO(); + // 拷贝 + BeanUtils.copyProperties(inboundRankDTO, inboundRankDO, IgnoreNullUtil.getNullPropertyNames(inboundRankDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + return inboundRankDO; + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/outboundRank/OutboundRankAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/outboundRank/OutboundRankAssembler.java new file mode 100644 index 000000000..8388a919f --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/outboundRank/OutboundRankAssembler.java @@ -0,0 +1,36 @@ +package com.mhd.wms.interfaces.assember.outboundRank; + +import cn.hutool.core.util.ObjectUtil; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; +import com.mhd.wms.interfaces.dto.outboundRank.OutboundRankDTO; +import org.springframework.stereotype.Component; + +/** + * 出库排名统计Assembler + * + * @author rcx + * @date 2026-08-31 + */ +@Component +public class OutboundRankAssembler { + + /** + * 转换实体 + */ + public OutboundRankDO toDO(OutboundRankDTO outboundRankDTO) { + OutboundRankDO outboundRankDO = new OutboundRankDO(); + // 拷贝 + BeanUtils.copyProperties(outboundRankDTO, outboundRankDO, IgnoreNullUtil.getNullPropertyNames(outboundRankDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + return outboundRankDO; + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inboundRank/InboundRankDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inboundRank/InboundRankDTO.java new file mode 100644 index 000000000..e7c812636 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inboundRank/InboundRankDTO.java @@ -0,0 +1,45 @@ +package com.mhd.wms.interfaces.dto.inboundRank; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 入库排名统计入参DTO + * + *

按入仓日期区间筛选商品入库量统计排名,统计口径:入仓日期 + 仅已入库状态(5) + 明细仅取 level=1 主行; + * 一行 = 某仓单内某货品的合计,按件数降序排名

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class InboundRankDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("入仓日期-开始 yyyy-MM-dd(必填,按入仓单入仓日期筛选)") + private String warehouseDateStart; + + @ApiModelProperty("入仓日期-结束 yyyy-MM-dd(必填,按入仓单入仓日期筛选)") + private String warehouseDateEnd; + + @ApiModelProperty("仓单编号/入库单号(模糊)") + private String inOrderNumber; + + @ApiModelProperty("客户编号(模糊)") + private String shipperCode; + + @ApiModelProperty("存货人/客户名称(模糊)") + private String shipperName; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("货名/商品名称(模糊)") + private String materialName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outboundRank/OutboundRankDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outboundRank/OutboundRankDTO.java new file mode 100644 index 000000000..eac2c07b5 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outboundRank/OutboundRankDTO.java @@ -0,0 +1,43 @@ +package com.mhd.wms.interfaces.dto.outboundRank; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 出库排名统计入参DTO + * + *

按日期区间统计商品/线路出库量排名,统计口径:出库单创建时间 + 已出库及之后状态(9,12,13)

+ * + * @author rcx + * @date 2026-08-31 + */ +@Data +public class OutboundRankDTO { + + @ApiModelProperty("出库日期-开始 yyyy-MM-dd(必填,按出库单创建时间统计)") + private String createTimeStart; + + @ApiModelProperty("出库日期-结束 yyyy-MM-dd(必填,按出库单创建时间统计)") + private String createTimeEnd; + + @ApiModelProperty("商品货号(模糊)") + private String materialCode; + + @ApiModelProperty("商品名称(模糊)") + private String materialName; + + @ApiModelProperty("线路编码(模糊)") + private String lineCode; + + @ApiModelProperty("线路名称(模糊)") + private String lineName; + + @ApiModelProperty("仓库名称(模糊)") + private String warehouseName; + + @ApiModelProperty("客户名称(模糊)") + private String customerName; + + @ApiModelProperty("货主名称(模糊)") + private String shipperName; +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/inboundRank/InboundRankApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/inboundRank/InboundRankApi.java new file mode 100644 index 000000000..b979e988b --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/inboundRank/InboundRankApi.java @@ -0,0 +1,105 @@ +package com.mhd.wms.interfaces.facadeApi.inboundRank; + +import com.github.pagehelper.PageInfo; +import com.mhd.common.core.constant.HttpStatus; +import com.mhd.common.core.utils.PageUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; +import com.mhd.wms.application.service.inboundRank.InboundRankApplicationService; +import com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO; +import com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO; +import com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO; +import com.mhd.wms.interfaces.assember.inboundRank.InboundRankAssembler; +import com.mhd.wms.interfaces.dto.inboundRank.InboundRankDTO; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; + +/** + * 入库排名统计Api + * + *

按入仓日期区间筛选商品入库量统计排名。统计口径:入仓日期 + 仅已入库状态(5), + * 明细仅取 level=1 主行;一行 = 某仓单内某货品的合计,按件数降序排名。 + * 字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨)/投保总额/体积(CBM)。 + * 与出库排名(/outboundRankApi)配对,前端用 tab 页区分

+ * + * @author rcx + * @date 2026-08-31 + */ +@RestController +@RequestMapping("/inboundRankApi") +public class InboundRankApi { + + @Resource + private InboundRankAssembler inboundRankAssembler; + + @Autowired + private InboundRankApplicationService inboundRankApplicationService; + + /** + * 分页查询商品入库排名列表(含合计行) + */ + @ApiOperation("分页查询商品入库排名列表") + @GetMapping("/queryMaterialRankList") + public HashMap queryMaterialRankList(InboundRankDTO inboundRankDTO) { + //转换实体 + InboundRankDO inboundRankDO = inboundRankAssembler.toDO(inboundRankDTO); + startPage(); + List list = inboundRankApplicationService.queryMaterialRankList(inboundRankDO); + InboundRankTotalPO total = inboundRankApplicationService.queryMaterialRankTotal(inboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 导出商品入库排名Excel + */ + @ApiOperation("导出商品入库排名Excel") + @GetMapping("/exportMaterialRank") + public void exportMaterialRank(HttpServletResponse response, InboundRankDTO inboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + InboundRankDO inboundRankDO = inboundRankAssembler.toDO(inboundRankDTO); + List list = inboundRankApplicationService.exportMaterialRank(inboundRankDO); + + String fileName = URLEncoder.encode("入库排名统计", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(InboundMaterialRankPO.class); + util.exportExcel(response, list, "入库排名统计"); + } + + /** + * 分页结果 + 合计行:data/total/code/msg 之外追加 + * totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount + */ + private HashMap getDataTableWithTotal(List list, InboundRankTotalPO total) { + HashMap result = new HashMap<>(); + result.put("data", list); + result.put("total", new PageInfo<>(list).getTotal()); + result.put("code", HttpStatus.SUCCESS); + result.put("msg", "查询成功"); + if (total != null) { + result.put("totalPieceCount", total.getTotalPieceCount()); + result.put("totalGrossWeightTon", total.getTotalGrossWeightTon()); + result.put("totalInsureAmount", total.getTotalInsureAmount()); + result.put("totalVolume", total.getTotalVolume()); + result.put("totalOrderCount", total.getTotalOrderCount()); + } + return result; + } + + /** + * 设置请求分页数据 + */ + protected void startPage() { + PageUtils.startPage(); + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java new file mode 100644 index 000000000..439dbba78 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java @@ -0,0 +1,134 @@ +package com.mhd.wms.interfaces.facadeApi.outboundRank; + +import com.github.pagehelper.PageInfo; +import com.mhd.common.core.constant.HttpStatus; +import com.mhd.common.core.utils.PageUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; +import com.mhd.wms.application.service.outboundRank.OutboundRankApplicationService; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO; +import com.mhd.wms.domain.outboundRank.repository.po.OutboundRankTotalPO; +import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO; +import com.mhd.wms.interfaces.assember.outboundRank.OutboundRankAssembler; +import com.mhd.wms.interfaces.dto.outboundRank.OutboundRankDTO; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.List; + +/** + * 出库排名统计Api + * + *

按日期区间筛选,统计商品/线路出库量排名。统计口径:出库单创建时间 + 已出库及之后状态(9,12,13), + * 明细仅取 level=1 主行;销售量=SUM(出库数量)、交易数=COUNT(DISTINCT 出库单号)、金额=SUM(明细总价)

+ * + * @author rcx + * @date 2026-08-31 + */ +@RestController +@RequestMapping("/outboundRankApi") +public class OutboundRankApi { + + @Resource + private OutboundRankAssembler outboundRankAssembler; + + @Autowired + private OutboundRankApplicationService outboundRankApplicationService; + + /** + * 分页查询商品出库排名列表(含合计行) + */ + @ApiOperation("分页查询商品出库排名列表") + @GetMapping("/queryMaterialRankList") + public HashMap queryMaterialRankList(OutboundRankDTO outboundRankDTO) { + //转换实体 + OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO); + startPage(); + List list = outboundRankApplicationService.queryMaterialRankList(outboundRankDO); + OutboundRankTotalPO total = outboundRankApplicationService.queryMaterialRankTotal(outboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 分页查询线路出库排名列表(含合计行) + */ + @ApiOperation("分页查询线路出库排名列表") + @GetMapping("/queryLineRankList") + public HashMap queryLineRankList(OutboundRankDTO outboundRankDTO) { + //转换实体 + OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO); + startPage(); + List list = outboundRankApplicationService.queryLineRankList(outboundRankDO); + OutboundRankTotalPO total = outboundRankApplicationService.queryLineRankTotal(outboundRankDO); + return getDataTableWithTotal(list, total); + } + + /** + * 导出商品出库排名Excel + */ + @ApiOperation("导出商品出库排名Excel") + @GetMapping("/exportMaterialRank") + public void exportMaterialRank(HttpServletResponse response, OutboundRankDTO outboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO); + List list = outboundRankApplicationService.exportMaterialRankList(outboundRankDO); + + String fileName = URLEncoder.encode("商品出库排名", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(OutboundMaterialRankPO.class); + util.exportExcel(response, list, "商品出库排名"); + } + + /** + * 导出线路出库排名Excel + */ + @ApiOperation("导出线路出库排名Excel") + @GetMapping("/exportLineRank") + public void exportLineRank(HttpServletResponse response, OutboundRankDTO outboundRankDTO) throws Exception { + //转换实体(不分页,导出全量) + OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO); + List list = outboundRankApplicationService.exportLineRankList(outboundRankDO); + + String fileName = URLEncoder.encode("线路出库排名", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + ExcelUtil util = new ExcelUtil<>(OutboundLineRankPO.class); + util.exportExcel(response, list, "线路出库排名"); + } + + /** + * 分页结果 + 合计行:data/total/code/msg 之外追加 totalSalesQuantity/totalTradeCount/totalAmount + */ + private HashMap getDataTableWithTotal(List list, OutboundRankTotalPO total) { + HashMap result = new HashMap<>(); + result.put("data", list); + result.put("total", new PageInfo<>(list).getTotal()); + result.put("code", HttpStatus.SUCCESS); + result.put("msg", "查询成功"); + if (total != null) { + result.put("totalSalesQuantity", total.getTotalSalesQuantity()); + result.put("totalTradeCount", total.getTotalTradeCount()); + result.put("totalAmount", total.getTotalAmount()); + } + return result; + } + + /** + * 设置请求分页数据 + */ + protected void startPage() { + PageUtils.startPage(); + } +} diff --git a/mhd_wms/src/main/resources/mapper/inboundRank/InboundRankMapper.xml b/mhd_wms/src/main/resources/mapper/inboundRank/InboundRankMapper.xml new file mode 100644 index 000000000..fc1e6f238 --- /dev/null +++ b/mhd_wms/src/main/resources/mapper/inboundRank/InboundRankMapper.xml @@ -0,0 +1,104 @@ + + + + + + + a.del_flag = 1 + and a.level = 1 + and b.status = 5 + + and b.top_organization_id = #{topOrganizationId} + + + and b.warehouse_id = #{warehouseId} + + + and b.warehouse_name like concat('%', #{warehouseName}, '%') + + + and b.in_order_number like concat('%', #{inOrderNumber}, '%') + + + and b.shipper_code like concat('%', #{shipperCode}, '%') + + + and b.shipper_name like concat('%', #{shipperName}, '%') + + + and a.material_code like concat('%', #{materialCode}, '%') + + + and a.material_name like concat('%', #{materialName}, '%') + + + and date_format(b.warehouse_date,'%Y-%m-%d') >= #{warehouseDateStart} + + + and date_format(b.warehouse_date,'%Y-%m-%d') <= #{warehouseDateEnd} + + + + + from in_material_detail a + join stock_in_order b on a.in_order_number = b.in_order_number and b.del_flag = 1 + left join material_base_info c on a.material_base_info_id = c.material_base_info_id + + + + + + + + diff --git a/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml b/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml new file mode 100644 index 000000000..54aa7458b --- /dev/null +++ b/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml @@ -0,0 +1,126 @@ + + + + + + + a.del_flag = 1 + and a.level = 1 + and b.status in (9, 12, 13) + + and b.top_organization_id = #{topOrganizationId} + + + and b.warehouse_id = #{warehouseId} + + + and b.warehouse_name like concat('%', #{warehouseName}, '%') + + + and b.customer_name like concat('%', #{customerName}, '%') + + + and b.shipper_name like concat('%', #{shipperName}, '%') + + + and b.line_code like concat('%', #{lineCode}, '%') + + + and b.line_name like concat('%', #{lineName}, '%') + + + and date_format(b.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(b.create_time,'%Y-%m-%d') <= #{createTimeEnd} + + + + + from out_material_detail a + join stock_out_order b on a.out_order_number = b.out_order_number and b.del_flag = 1 + + + + + + + + + + + + + +