7 changed files with 200 additions and 0 deletions
-
27src/main/java/com/gaotao/modules/warehouse/controller/LabelInventoryStockController.java
-
19src/main/java/com/gaotao/modules/warehouse/dao/LabelInventoryStockMapper.java
-
22src/main/java/com/gaotao/modules/warehouse/entity/dto/LabelInventoryStockQueryDto.java
-
23src/main/java/com/gaotao/modules/warehouse/entity/vo/LabelInventoryStockRow.java
-
10src/main/java/com/gaotao/modules/warehouse/service/LabelInventoryStockService.java
-
49src/main/java/com/gaotao/modules/warehouse/service/impl/LabelInventoryStockServiceImpl.java
-
50src/main/resources/mapper/warehouse/LabelInventoryStockMapper.xml
@ -0,0 +1,27 @@ |
|||||
|
package com.gaotao.modules.warehouse.controller; |
||||
|
|
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.common.utils.R; |
||||
|
import com.gaotao.modules.warehouse.entity.dto.LabelInventoryStockQueryDto; |
||||
|
import com.gaotao.modules.warehouse.service.LabelInventoryStockService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
/** 新版库存管理查询入口,与仍供旧页面使用的inventory_stock接口隔离 - rqrq */ |
||||
|
@RestController |
||||
|
@RequestMapping("/warehouse") |
||||
|
public class LabelInventoryStockController { |
||||
|
@Autowired |
||||
|
private LabelInventoryStockService labelInventoryStockService; |
||||
|
|
||||
|
/** 页面查询及分批导出共用POST,分页统一返回page,Controller不处理聚合或业务校验 - rqrq */ |
||||
|
@PostMapping("getLabelInventoryStockList") |
||||
|
public R getLabelInventoryStockList(@RequestBody LabelInventoryStockQueryDto query) { |
||||
|
// 委托Service按请求工厂校验并查询标签汇总,失败交由统一异常处理 - rqrq |
||||
|
PageUtils page = labelInventoryStockService.getLabelInventoryStockList(query); |
||||
|
return R.ok().put("page", page); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
package com.gaotao.modules.warehouse.dao; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import com.gaotao.modules.warehouse.entity.dto.LabelInventoryStockQueryDto; |
||||
|
import com.gaotao.modules.warehouse.entity.vo.LabelInventoryStockRow; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
/** 标签库存汇总独立只读Mapper,不接入旧库存更新流程 - rqrq */ |
||||
|
@Mapper |
||||
|
public interface LabelInventoryStockMapper { |
||||
|
/** 统计分组后的库存行数;与列表共用筛选,避免SQL Server的带ORDER BY子查询计数错误 - rqrq */ |
||||
|
long countLabelInventoryStock(@Param("query") LabelInventoryStockQueryDto query); |
||||
|
|
||||
|
/** 按六个库存维度聚合后分页;NOLOCK允许脏读,仅供查询和导出,不用于库存扣减依据 - rqrq */ |
||||
|
IPage<LabelInventoryStockRow> getLabelInventoryStockList( |
||||
|
Page<LabelInventoryStockRow> page, @Param("query") LabelInventoryStockQueryDto query); |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
package com.gaotao.modules.warehouse.entity.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** 标签库存汇总查询入参,仅用于只读页面及导出,不映射inventory_stock - rqrq */ |
||||
|
@Data |
||||
|
public class LabelInventoryStockQueryDto { |
||||
|
/** 页面明确传入的标签工厂编码,默认来自当前用户site;精确匹配handling_unit.site,必填不落库 - rqrq */ |
||||
|
private String site; |
||||
|
/** 仓库筛选,精确匹配handling_unit.warehouse_id;空值不过滤,不落库 - rqrq */ |
||||
|
private String warehouseId; |
||||
|
/** 物料编码筛选,沿用原页面包含匹配;空值不过滤,不落库 - rqrq */ |
||||
|
private String partNo; |
||||
|
/** 批次筛选,沿用原页面包含匹配;空值不过滤,不落库 - rqrq */ |
||||
|
private String batchNo; |
||||
|
/** 库位筛选,沿用原页面包含匹配;空值不过滤,不落库 - rqrq */ |
||||
|
private String locationId; |
||||
|
/** 汇总结果页码,从1开始;页面和分批导出共用,不落库 - rqrq */ |
||||
|
private Integer page = 1; |
||||
|
/** 每页汇总行数,默认20,最大1000以支持分批导出;不是标签条数,不落库 - rqrq */ |
||||
|
private Integer size = 20; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
package com.gaotao.modules.warehouse.entity.vo; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** handling_unit分组后的只读库存行,供库存管理页面和导出消费,不落库 - rqrq */ |
||||
|
@Data |
||||
|
public class LabelInventoryStockRow { |
||||
|
/** 分组工厂,来源handling_unit.site;保持标签实际工厂,不转换父site - rqrq */ |
||||
|
private String site; |
||||
|
/** 分组仓库,来源handling_unit.warehouse_id;不落库 - rqrq */ |
||||
|
private String warehouseId; |
||||
|
/** 分组物料编码,来源handling_unit.part_no;不落库 - rqrq */ |
||||
|
private String partNo; |
||||
|
/** 分组批次,来源handling_unit.batch_no;不落库 - rqrq */ |
||||
|
private String batchNo; |
||||
|
/** 分组库位,来源handling_unit.location_id;不落库 - rqrq */ |
||||
|
private String locationId; |
||||
|
/** 分组WDR,来源handling_unit.wdr,空值保持原值,不混并不同WDR - rqrq */ |
||||
|
private String wdr; |
||||
|
/** 现有库存:同组在库标签qty之和,沿用物料库存单位;含冻结/预留,不等同可用库存 - rqrq */ |
||||
|
private BigDecimal qtyOnHand = BigDecimal.ZERO; |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
package com.gaotao.modules.warehouse.service; |
||||
|
|
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.modules.warehouse.entity.dto.LabelInventoryStockQueryDto; |
||||
|
|
||||
|
/** 库存管理新版页面的标签聚合查询,不负责库存写入或旧库存接口兼容 - rqrq */ |
||||
|
public interface LabelInventoryStockService { |
||||
|
/** 校验工厂/分页并返回标签库存聚合分页;失败抛业务异常,不静默返回错误库存 - rqrq */ |
||||
|
PageUtils getLabelInventoryStockList(LabelInventoryStockQueryDto query); |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
package com.gaotao.modules.warehouse.service.impl; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import com.gaotao.common.exception.XJException; |
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.modules.warehouse.dao.LabelInventoryStockMapper; |
||||
|
import com.gaotao.modules.warehouse.entity.dto.LabelInventoryStockQueryDto; |
||||
|
import com.gaotao.modules.warehouse.entity.vo.LabelInventoryStockRow; |
||||
|
import com.gaotao.modules.warehouse.service.LabelInventoryStockService; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
/** 只读标签库存查询:不写表、不调用IFS/WCS,NOLOCK的非一致读风险只限查询结果 - rqrq */ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class LabelInventoryStockServiceImpl implements LabelInventoryStockService { |
||||
|
@Autowired |
||||
|
private LabelInventoryStockMapper labelInventoryStockMapper; |
||||
|
|
||||
|
/** 必须使用请求site,保留旧筛选的精确/包含语义;限制单批规模,不影响业务库存更新 - rqrq */ |
||||
|
@Override |
||||
|
public PageUtils getLabelInventoryStockList(LabelInventoryStockQueryDto query) { |
||||
|
if (query == null || StringUtils.isBlank(query.getSite())) { |
||||
|
throw new XJException("工厂编码不能为空"); |
||||
|
} |
||||
|
if (query.getPage() == null || query.getPage() < 1) { |
||||
|
throw new XJException("页码必须大于0"); |
||||
|
} |
||||
|
if (query.getSize() == null || query.getSize() < 1 || query.getSize() > 1000) { |
||||
|
throw new XJException("每页数量必须在1到1000之间,请分批查询或导出"); |
||||
|
} |
||||
|
// 仅清理查询输入两端空格,不推断父工厂、不增加冻结/预留/立库状态限制 - rqrq |
||||
|
query.setSite(query.getSite().trim()); |
||||
|
query.setWarehouseId(StringUtils.trimToNull(query.getWarehouseId())); |
||||
|
query.setPartNo(StringUtils.trimToNull(query.getPartNo())); |
||||
|
query.setBatchNo(StringUtils.trimToNull(query.getBatchNo())); |
||||
|
query.setLocationId(StringUtils.trimToNull(query.getLocationId())); |
||||
|
// 单独统计聚合行数,避免分页插件将含ORDER BY的原SQL包成SQL Server不支持的计数子查询 - rqrq |
||||
|
long total = labelInventoryStockMapper.countLabelInventoryStock(query); |
||||
|
Page<LabelInventoryStockRow> page = new Page<>(query.getPage(), query.getSize(), false); |
||||
|
page.setTotal(total); |
||||
|
// Mapper按相同筛选先SUM再分页;失败直接传播,前端结束loading并展示错误,不返回伪造库存 - rqrq |
||||
|
IPage<LabelInventoryStockRow> result = labelInventoryStockMapper.getLabelInventoryStockList(page, query); |
||||
|
return new PageUtils(result); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.gaotao.modules.warehouse.dao.LabelInventoryStockMapper"> |
||||
|
<!-- 列表和计数共用筛选,均按请求site精确查询;无锁读取风险见下方说明 - rqrq --> |
||||
|
<sql id="labelInventoryFilter"> |
||||
|
WHERE h.site = #{query.site} |
||||
|
AND h.in_stock_flag = 'Y' |
||||
|
<if test="query.warehouseId != null and query.warehouseId != ''"> |
||||
|
AND h.warehouse_id = #{query.warehouseId} |
||||
|
</if> |
||||
|
<if test="query.partNo != null and query.partNo != ''"> |
||||
|
AND h.part_no LIKE '%' + #{query.partNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.batchNo != null and query.batchNo != ''"> |
||||
|
AND h.batch_no LIKE '%' + #{query.batchNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.locationId != null and query.locationId != ''"> |
||||
|
AND h.location_id LIKE '%' + #{query.locationId} + '%' |
||||
|
</if> |
||||
|
</sql> |
||||
|
|
||||
|
<!-- 只统计库存分组,不统计标签数;计数子查询不含ORDER BY,兼容SQL Server - rqrq --> |
||||
|
<select id="countLabelInventoryStock" resultType="java.lang.Long"> |
||||
|
SELECT COUNT_BIG(1) |
||||
|
FROM ( |
||||
|
SELECT 1 AS groupValue |
||||
|
FROM handling_unit h WITH (NOLOCK) |
||||
|
<include refid="labelInventoryFilter"/> |
||||
|
GROUP BY h.site, h.warehouse_id, h.part_no, h.batch_no, h.location_id, h.wdr |
||||
|
) inventoryGroups |
||||
|
</select> |
||||
|
<!-- |
||||
|
现有库存以标签在库标记Y为唯一状态口径,保留冻结/预留标签,不关联栈板或inventory_stock。 |
||||
|
按用户要求使用NOLOCK:并发更新时允许脏读、漏读或重复读取,统计/导出不是一致性快照,禁止作为扣库存依据。 |
||||
|
必须先GROUP BY再分页,ORDER BY覆盖全部分组键,避免同库存维度跨页顺序不确定。 - rqrq |
||||
|
--> |
||||
|
<select id="getLabelInventoryStockList" resultType="com.gaotao.modules.warehouse.entity.vo.LabelInventoryStockRow"> |
||||
|
SELECT h.site AS site, |
||||
|
h.warehouse_id AS warehouseId, |
||||
|
h.part_no AS partNo, |
||||
|
h.batch_no AS batchNo, |
||||
|
h.location_id AS locationId, |
||||
|
h.wdr AS wdr, |
||||
|
SUM(ISNULL(h.qty, 0)) AS qtyOnHand |
||||
|
FROM handling_unit h WITH (NOLOCK) |
||||
|
<include refid="labelInventoryFilter"/> |
||||
|
GROUP BY h.site, h.warehouse_id, h.part_no, h.batch_no, h.location_id, h.wdr |
||||
|
ORDER BY h.site, h.warehouse_id, h.part_no, h.batch_no, h.location_id, h.wdr |
||||
|
</select> |
||||
|
</mapper> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue