feat(wms,oms):出库排名统计改造为仓单×货品明细列表,按出库数量降序排名

- 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null,数据来源待确认)/出仓日期

- 商品/线路各一套接口,路径名不变;商品接口忽略线路筛选参数,线路接口忽略商品筛选参数;含合计行(件数/毛重吨/体积/仓单数)与Excel导出

- 统计口径不变:出库单创建时间区间+已出库状态(9,12,13)+明细level=1主行;排序按出库数量(销售量)降序,件数/出仓日期/单号次之

- 数据源:WMS查本库出库表;OMS跨库查NGWL_TEST_WMS同名表(OMS库出库单状态不流转,跨库与WMS端数字一致)

- 删除原按商品/线路聚合的排名接口(销售量/交易数/金额字段)
This commit is contained in:
rcx
2026-09-02 15:25:51 +08:00
parent e821619a96
commit 3af78d5d7b
28 changed files with 554 additions and 684 deletions
@@ -4,9 +4,8 @@ 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.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
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;
@@ -27,11 +26,11 @@ import java.util.List;
/**
* 出库排名统计Api
*
* <p>按日期区间筛选,统计商品/线路出库量排名。OMS 库出库单状态不流转(无"已出库"数据),
* 数据源跨库取 WMS 库出库表(NGWL_TEST_WMS.stock_out_order / out_material_detail),
* 口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;
* 统计条件:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行;
* 销售量=SUM(出库数量)、交易数=COUNT(DISTINCT 出库单号)、金额=SUM(明细总价)</p>
* <p>按日期区间筛选出库明细列表(一行 = 仓单×货品,件数/毛重/体积按行汇总,按出库数量(销售量)降序,件数/出仓日期/单号次之)。
* OMS 库出库单状态不流转(无"已出库"数据),数据源跨库取 WMS 库出库表(NGWL_TEST_WMS.stock_out_order / out_material_detail),
* 口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;统计条件:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行。
* 商品/线路两个 tab 各自独立接口,内部为同一份明细查询:商品接口忽略线路筛选参数,线路接口忽略商品筛选参数。
* 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null)/出仓日期</p>
*
* @author rcx
* @date 2026-08-31
@@ -48,84 +47,97 @@ public class ExecutionOutboundRankApi {
private ExecutionOutboundRankApplicationService executionOutboundRankApplicationService;
/**
* 分页查询商品出库排名列表(含合计行)
* 分页查询商品出库排名列表(含合计行,商品tab;忽略线路筛选参数
*/
@ApiOperation("分页查询商品出库排名列表")
@GetMapping("/queryMaterialRankList")
public HashMap<String, Object> queryMaterialRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
//转换实体
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
//商品tab:忽略线路筛选参数
executionOutboundRankDO.setLineCode(null);
executionOutboundRankDO.setLineName(null);
startPage();
List<ExecutionOutboundMaterialRankPO> list = executionOutboundRankApplicationService.queryMaterialRankList(executionOutboundRankDO);
ExecutionOutboundRankTotalPO total = executionOutboundRankApplicationService.queryMaterialRankTotal(executionOutboundRankDO);
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
return getDataTableWithTotal(list, total);
}
/**
* 分页查询线路出库排名列表(含合计行)
* 分页查询线路出库排名列表(含合计行,线路tab;忽略商品筛选参数
*/
@ApiOperation("分页查询线路出库排名列表")
@GetMapping("/queryLineRankList")
public HashMap<String, Object> queryLineRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
//转换实体
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
//线路tab:忽略商品筛选参数
executionOutboundRankDO.setMaterialCode(null);
executionOutboundRankDO.setMaterialName(null);
startPage();
List<ExecutionOutboundLineRankPO> list = executionOutboundRankApplicationService.queryLineRankList(executionOutboundRankDO);
ExecutionOutboundRankTotalPO total = executionOutboundRankApplicationService.queryLineRankTotal(executionOutboundRankDO);
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
return getDataTableWithTotal(list, total);
}
/**
* 导出商品出库排名Excel
* 导出商品出库排名Excel(商品tab;忽略线路筛选参数)
*/
@ApiOperation("导出商品出库排名Excel")
@GetMapping("/exportMaterialRank")
public void exportMaterialRank(HttpServletResponse response, ExecutionOutboundRankDTO executionOutboundRankDTO) throws Exception {
//转换实体(不分页,导出全量)
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
List<ExecutionOutboundMaterialRankPO> list = executionOutboundRankApplicationService.exportMaterialRankList(executionOutboundRankDO);
//商品tab:忽略线路筛选参数
executionOutboundRankDO.setLineCode(null);
executionOutboundRankDO.setLineName(null);
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.exportDetailList(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);
ExcelUtil<ExecutionOutboundDetailRankPO> util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
util.exportExcel(response, list, "商品出库排名");
}
/**
* 导出线路出库排名Excel
* 导出线路出库排名Excel(线路tab;忽略商品筛选参数)
*/
@ApiOperation("导出线路出库排名Excel")
@GetMapping("/exportLineRank")
public void exportLineRank(HttpServletResponse response, ExecutionOutboundRankDTO executionOutboundRankDTO) throws Exception {
//转换实体(不分页,导出全量)
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
List<ExecutionOutboundLineRankPO> list = executionOutboundRankApplicationService.exportLineRankList(executionOutboundRankDO);
//线路tab:忽略商品筛选参数
executionOutboundRankDO.setMaterialCode(null);
executionOutboundRankDO.setMaterialName(null);
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.exportDetailList(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);
ExcelUtil<ExecutionOutboundDetailRankPO> util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
util.exportExcel(response, list, "线路出库排名");
}
/**
* 分页结果 + 合计行:data/total/code/msg 之外追加 totalSalesQuantity/totalTradeCount/totalAmount
* 分页结果 + 合计行:data/total/code/msg 之外追加 totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount
*/
private HashMap<String, Object> getDataTableWithTotal(List<?> list, ExecutionOutboundRankTotalPO total) {
private HashMap<String, Object> getDataTableWithTotal(List<?> list, ExecutionOutboundDetailRankTotalPO 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());
result.put("totalPieceCount", total.getTotalPieceCount());
result.put("totalGrossWeightTon", total.getTotalGrossWeightTon());
result.put("totalVolume", total.getTotalVolume());
result.put("totalOrderCount", total.getTotalOrderCount());
}
return result;
}