feat(wms,oms):库存管理新增入库排名统计(按仓单+货品汇总,件数降序,与出库排名tab配对);还原出库排名第一版源码

入库排名统计(新增):WMS /inboundRankApi、OMS /executionInboundRankApi 的 queryMaterialRankList 分页+合计、exportMaterialRank 导出;口径:仅已入库(status=5),明细仅level=1主行,日期区间按入仓日期warehouse_date筛选(必填);一行=仓单内某货品合计(GROUP BY 仓单+货品 ORDER BY 件数DESC);字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨=KG/1000)/投保总额(货品档案保额,组内MAX防重复累加)/体积(CBM)+货号/规格/单位;合计行:totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount;登录上下文:日期必填校验+topOrganizationId租户隔离,WMS另注入关联仓库warehouseId。出库排名统计(还原第一版):/outboundRankApi、/executionOutboundRankApi,按货品/线路汇总排名
This commit is contained in:
rcx
2026-08-31 17:47:09 +08:00
parent a983ae639e
commit bf96f5f005
50 changed files with 2887 additions and 0 deletions
@@ -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
*
* <p>按入仓日期区间筛选商品入库量统计排名。统计口径:入仓日期 + 仅已入库状态(5),
* 明细仅取 level=1 主行;一行 = 某仓单内某货品的合计,按件数降序排名。
* 字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨)/投保总额/体积(CBM)。
* 与出库排名(/executionOutboundRankApi)配对,前端用 tab 页区分</p>
*
* @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<String, Object> queryMaterialRankList(ExecutionInboundRankDTO executionInboundRankDTO) {
//转换实体
ExecutionInboundRankDO executionInboundRankDO = executionInboundRankAssembler.toDO(executionInboundRankDTO);
startPage();
List<ExecutionInboundMaterialRankPO> 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<ExecutionInboundMaterialRankPO> 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<ExecutionInboundMaterialRankPO> util = new ExcelUtil<>(ExecutionInboundMaterialRankPO.class);
util.exportExcel(response, list, "入库排名统计");
}
/**
* 分页结果 + 合计行:data/total/code/msg 之外追加
* totalPieceCount/totalGrossWeightTon/totalInsureAmount/totalVolume/totalOrderCount
*/
private HashMap<String, Object> getDataTableWithTotal(List<?> list, ExecutionInboundRankTotalPO total) {
HashMap<String, Object> 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();
}
}
@@ -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
*
* <p>按日期区间筛选,统计商品/线路出库量排名。统计口径:执行出库单创建时间 + 已出库状态(9),
* 明细仅取 level=1 主行;销售量=SUM(出库数量)、交易数=COUNT(DISTINCT 出库单号)、金额=SUM(明细总价)</p>
*
* @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<String, Object> queryMaterialRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
//转换实体
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
startPage();
List<ExecutionOutboundMaterialRankPO> list = executionOutboundRankApplicationService.queryMaterialRankList(executionOutboundRankDO);
ExecutionOutboundRankTotalPO total = executionOutboundRankApplicationService.queryMaterialRankTotal(executionOutboundRankDO);
return getDataTableWithTotal(list, total);
}
/**
* 分页查询线路出库排名列表(含合计行)
*/
@ApiOperation("分页查询线路出库排名列表")
@GetMapping("/queryLineRankList")
public HashMap<String, Object> queryLineRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
//转换实体
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
startPage();
List<ExecutionOutboundLineRankPO> 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<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundLineRankPO> 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<ExecutionOutboundLineRankPO> util = new ExcelUtil<>(ExecutionOutboundLineRankPO.class);
util.exportExcel(response, list, "线路出库排名");
}
/**
* 分页结果 + 合计行:data/total/code/msg 之外追加 totalSalesQuantity/totalTradeCount/totalAmount
*/
private HashMap<String, Object> getDataTableWithTotal(List<?> list, ExecutionOutboundRankTotalPO total) {
HashMap<String, Object> 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();
}
}