feat(oms,wms):库存导出按到期日分组排序并合并同物料同到期日库存(仅wlExpiry查询生效)

需求:库存查询导出按商品到期日分组归类、相同到期日相邻显示,相同物料相同
到期日合并库存。仅在 queryRule=wlExpiry(物料+到期日汇总查询)导出时生效,
列表显示不变;同时回退 8fedb6d6 对列表默认排序的改动。

一、列表默认查询还原(回退 8fedb6d6):OMS queryList 恢复 order by a.update_time desc,
    Api 恢复 update_time 内存重排(空值最后),两侧列表排序与改动前一致。
二、导出排序(OMS/WMS queryListByWlExpiry):/list 新增可选参数 orderByExpiryDate,
    仅 queryRule=wlExpiry 时生效:
    1. wlExpiry + orderByExpiryDate=true(导出):到期日倒序(日期近的在前)、空值最后、
       0库存靠后、同到期日按更新时间倒序;排序在SQL层,跨页/全量导出分组不被打散;
       OMS Api 传参时跳过 update_time 内存重排,避免覆盖SQL排序
    2. 仅 wlExpiry 不带参数:排序保持原样(sort_order+更新时间倒序)
    3. 其他查询方式:不受影响,参数被忽略
三、合并:wlExpiry 查询 GROUP BY 物料+到期日+货主(货主隔离),相同物料相同到期日
    合并一行,库存/可用/冻结数量及净重/毛重/体积/面积 SUM 汇总(复用现成查询,未改)
四、前端导出:/list + queryRule=wlExpiry + orderByExpiryDate=true + 当前查询条件(不分页)
This commit is contained in:
rcx
2026-08-21 15:13:28 +08:00
parent 3aec384ba0
commit 22f2b66ffa
6 changed files with 52 additions and 12 deletions
@@ -255,4 +255,7 @@ public class ReservationMaterialInventoryDO extends MaterialBaseDO {
private String productionDateStr;
private String expiryDateStart;
private String expiryDateEnd;
@ApiModelProperty("导出按到期日分组排序标识:仅 queryRule=wlExpiry 时生效,true-到期日倒序(日期近的在前、空值最后、0库存靠后);不传-保持原有排序")
private Boolean orderByExpiryDate;
}
@@ -52,7 +52,8 @@ public class ReservationMaterialInventoryApi extends BaseController {
public TableDataInfo list(ReservationMaterialInventoryDTO materialInventoryDTO,
@RequestParam(value = "customerName", required = false) String customerName,
@RequestParam(value = "expiryDateStart", required = false) String expiryDateStart,
@RequestParam(value = "expiryDateEnd", required = false) String expiryDateEnd)
@RequestParam(value = "expiryDateEnd", required = false) String expiryDateEnd,
@RequestParam(value = "orderByExpiryDate", required = false) Boolean orderByExpiryDate)
{
// 出库分配前端传的是客户名称 customerName,这里通过名称查询货主ID,使用精确匹配(不模糊匹配)
String shipperName = null; // 保存查询到的货主名称
@@ -82,12 +83,24 @@ public class ReservationMaterialInventoryApi extends BaseController {
materialInventoryDO.setProductionDateStr(materialInventoryDTO.getProductionDate());
materialInventoryDO.setExpiryDateStart(expiryDateStart);
materialInventoryDO.setExpiryDateEnd(expiryDateEnd);
// 导出场景:queryRule=wlExpiry + orderByExpiryDate=true 时 SQL 按到期日倒序分组
// (日期近的在前、空值最后、0库存靠后、同到期日按更新时间倒序)
materialInventoryDO.setOrderByExpiryDate(orderByExpiryDate);
startPage();
// 使用带批次属性的查询方法,批次属性值从库存表中获取
// 排序由 SQL 统一处理:到期日倒序(日期近的在前、空值最后)、同到期日按更新时间倒序(空值最后),
// 查询列表与导出(同一接口)均按到期日分组,相同到期日的数据相邻显示;
// 不在内存重排,避免覆盖 SQL 排序导致跨页分组被打散
List<ReservationMaterialInventoryPO> list = materialInventoryApplicationService.queryListWithBatchAttributes(materialInventoryDO);
// 按更新时间倒序排序;update_time 为空的数据放最后
// (导出 orderByExpiryDate=true 时跳过该重排,避免覆盖 SQL 的到期日分组排序)
if (!Boolean.TRUE.equals(orderByExpiryDate)) {
list.sort((o1, o2) -> {
Date t1 = o1.getUpdateTime();
Date t2 = o2.getUpdateTime();
if (t1 == null && t2 == null) return 0;
if (t1 == null) return 1;
if (t2 == null) return -1;
return t2.compareTo(t1); // desc
});
}
TableDataInfo tableDataInfo = getDataTable(list);
return tableDataInfo;
}
@@ -292,11 +292,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectMaterialInventoryPo1"/>
<include refid="JoinMaterialBaseInfoPoWhere"/>
</where>
group by a.MATERIAL_INVENTORY_ID
<!-- 按到期日分组归类:到期日倒序(日期近的在前)、空值放最后;同到期日按更新时间倒序(空值放最后)。
查询列表与导出共用本查询,相同到期日的数据相邻显示;排序放 SQL 层保证跨页/全量导出分组不被打散 -->
order by CASE WHEN a.expiry_date IS NULL THEN 1 ELSE 0 END ASC, a.expiry_date DESC,
CASE WHEN a.update_time IS NULL THEN 1 ELSE 0 END ASC, a.update_time DESC
group by a.MATERIAL_INVENTORY_ID order by a.update_time desc
</select>
<select id="queryListByWlKw" parameterType="com.mhd.oms.domain.reservationMaterialInventory.repository.todo.ReservationMaterialInventoryDO" resultMap="MaterialInventoryResult">
@@ -373,7 +369,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
GROUP BY a.MATERIAL_BASE_INFO_ID, a.EXPIRY_DATE, a.shipper_id, a.shipper_code, a.shipper_name,
a.organization_id, a.organization_name, a.top_organization_id,
b.material_code, b.material_name
order by sort_order, MAX(a.update_time) desc
<!-- 导出(queryRule=wlExpiry + orderByExpiryDate=true)按到期日分组归类:到期日倒序(日期近的在前)、
空值放最后、0库存靠后、同到期日按更新时间倒序;相同物料+相同到期日合并为一行,数量类字段SUM汇总。
不传 orderByExpiryDate 保持原有排序 -->
<choose>
<when test="orderByExpiryDate != null and orderByExpiryDate == true">
order by CASE WHEN a.expiry_date IS NULL THEN 1 ELSE 0 END ASC, a.expiry_date DESC,
sort_order, MAX(a.update_time) DESC
</when>
<otherwise>
order by sort_order, MAX(a.update_time) desc
</otherwise>
</choose>
</select>
<select id="queryListByHz" parameterType="com.mhd.oms.domain.reservationMaterialInventory.repository.todo.ReservationMaterialInventoryDO" resultMap="MaterialInventoryResult">
@@ -233,6 +233,9 @@ public class MaterialInventoryDO extends MaterialBaseDO {
//查询规则 hz:货主,hzwl:货主+物料,wl:物料,kw:库位,wlkw:物料库位,all:全部(listAll 传入 hz 时会改为 hzwl
private String queryRule;
@ApiModelProperty("导出按到期日分组排序标识:仅 queryRule=wlExpiry 时生效,true-到期日倒序(日期近的在前、空值最后、0库存靠后);不传-保持原有排序")
private Boolean orderByExpiryDate;
@ApiModelProperty("冻结数量大于0条件")
@Excel(name = "冻结数量大于0条件")
private String greaterThanFreezeQuantity;
@@ -57,7 +57,8 @@ public class MaterialInventoryApi extends BaseController {
@RequestParam(value = "customerName", required = false) String customerName,
@RequestParam(value = "excludeZeroInventoryQuantity", required = false) Boolean excludeZeroInventoryQuantity,
@RequestParam(value = "expiryDateStart", required = false) String expiryDateStart,
@RequestParam(value = "expiryDateEnd", required = false) String expiryDateEnd)
@RequestParam(value = "expiryDateEnd", required = false) String expiryDateEnd,
@RequestParam(value = "orderByExpiryDate", required = false) Boolean orderByExpiryDate)
{
if (Boolean.TRUE.equals(excludeZeroInventoryQuantity)) {
materialInventoryDTO.setExcludeZeroInventoryQuantity(true);
@@ -90,6 +91,8 @@ public class MaterialInventoryApi extends BaseController {
materialInventoryDO.setProductionDateStr(materialInventoryDTO.getProductionDate());
materialInventoryDO.setExpiryDateStart(expiryDateStart);
materialInventoryDO.setExpiryDateEnd(expiryDateEnd);
// 导出场景:queryRule=wlExpiry + orderByExpiryDate=true 时 SQL 按到期日倒序分组(与 OMS 库存查询导出一致)
materialInventoryDO.setOrderByExpiryDate(orderByExpiryDate);
Date updateTime = materialInventoryDTO.getUpdateTime();
if (updateTime != null) {
LocalDateTime localDateTime = updateTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
@@ -491,7 +491,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
GROUP BY a.MATERIAL_BASE_INFO_ID, a.EXPIRY_DATE, a.shipper_id,
a.organization_id, a.top_organization_id
order by sort_order, MAX(a.update_time) desc
<!-- 导出(queryRule=wlExpiry + orderByExpiryDate=true)按到期日分组归类:到期日倒序(日期近的在前)、
空值放最后、0库存靠后、同到期日按更新时间倒序;相同物料+相同到期日合并为一行,数量类字段SUM汇总。
不传 orderByExpiryDate 保持原有排序 -->
<choose>
<when test="orderByExpiryDate != null and orderByExpiryDate == true">
order by CASE WHEN a.expiry_date IS NULL THEN 1 ELSE 0 END ASC, a.expiry_date DESC,
sort_order, MAX(a.update_time) DESC
</when>
<otherwise>
order by sort_order, MAX(a.update_time) desc
</otherwise>
</choose>
</select>
<!-- 按货主+物料汇总:A货主物料1、A货主物料2、B货主物料1、B货主物料2 为 4 行;库位取该货主+该物料下创建时间最新的一条明细 -->