From 7d53d31c3fe8e01d06d79e061bc0132303a0a1e4 Mon Sep 17 00:00:00 2001 From: Timi Date: Wed, 16 Sep 2026 15:15:19 +0800 Subject: [PATCH] add GaoProductStockBatchRequest --- .../GaoPackageConfigController.java | 4 +-- .../controller/GaoProductStockController.java | 13 +++++++ .../gao/mapper/GaoProductStockMapper.java | 3 ++ .../gao/service/GaoProductStockService.java | 3 ++ .../implement/GaoProductServiceImplement.java | 19 ++++++++++ .../GaoProductStockServiceImplement.java | 36 +++++++++++++++++-- .../gao/vo/GaoProductStockBatchRequest.java | 19 ++++++++++ .../gao/vo/GaoProductStockProductView.java | 5 +++ .../timi-server/gao/GaoProductStockMapper.xml | 19 ++++++++++ 9 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockBatchRequest.java diff --git a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPackageConfigController.java b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPackageConfigController.java index 840152d..0474edc 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPackageConfigController.java +++ b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPackageConfigController.java @@ -101,8 +101,8 @@ public class GaoPackageConfigController { if (skuIdList.isEmpty()) { return; } - Map skuMap = skuIdList.stream() - .collect(java.util.stream.Collectors.toMap(item -> item, skuService::detail)); + Map skuMap = skuService.listByIdList(skuIdList).stream() + .collect(java.util.stream.Collectors.toMap(GaoProductSku::getId, item -> item)); for (GaoPackageConfig config : configList) { for (GaoPackageConfigItem item : config.getItemList()) { item.setSku(skuMap.get(item.getSkuId())); diff --git a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoProductStockController.java b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoProductStockController.java index b8e4777..0bf0849 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoProductStockController.java +++ b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoProductStockController.java @@ -7,6 +7,7 @@ import com.imyeyu.api.modules.gao.entity.GaoProductStockRecord; import com.imyeyu.api.modules.gao.service.GaoProductStockService; import com.imyeyu.api.modules.gao.service.GaoProductStockRecordService; import com.imyeyu.api.modules.gao.service.GaoStoreScopeService; +import com.imyeyu.api.modules.gao.vo.GaoProductStockBatchRequest; import com.imyeyu.api.modules.gao.vo.GaoProductStockChangeRequest; import com.imyeyu.api.modules.gao.vo.GaoProductStockManualRevokeRequest; import com.imyeyu.api.modules.gao.vo.GaoProductStockPage; @@ -23,6 +24,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + /// GAO 产品库存接口 /// /// @author Codex @@ -64,6 +67,16 @@ public class GaoProductStockController { return stockService.detail(storeScopeService.resolveStoreId(storeId), skuId); } + @AOPLog + @RequestRateLimit + @RequireGaoPermission(GaoPermissionCode.PRODUCT_STOCK_READ) + @PostMapping("/batch-detail") + public List batchDetail(@RequestBody GaoProductStockBatchRequest request) { + TimiException.required(request, "not found stock batch request"); + request.setStoreId(storeScopeService.resolveStoreId(request.getStoreId())); + return stockService.batchDetail(request.getStoreId(), request.getSkuIdList()); + } + @AOPLog @RequestRateLimit @RequireGaoPermission(GaoPermissionCode.PRODUCT_STOCK_CREATE) diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoProductStockMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoProductStockMapper.java index f9f8f7f..ee280c6 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoProductStockMapper.java +++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoProductStockMapper.java @@ -32,6 +32,9 @@ public interface GaoProductStockMapper extends BaseMapper selectByStoreIdAndSkuIdList(@Param("storeId") String storeId, @Param("skuIdList") List skuIdList); + /// 条件更新库存余额 int updateQuantity(@Param("id") String id, @Param("onHandDelta") java.math.BigDecimal onHandDelta, @Param("reservedDelta") java.math.BigDecimal reservedDelta, @Param("updatedBy") String updatedBy); diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/GaoProductStockService.java b/src/main/java/com/imyeyu/api/modules/gao/service/GaoProductStockService.java index 3037e78..ffdd400 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/GaoProductStockService.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/GaoProductStockService.java @@ -26,6 +26,9 @@ public interface GaoProductStockService { /// 查询库存余额详情 GaoProductStock detail(String storeId, String skuId); + /// 批量查询指定 SKU 库存余额 + List batchDetail(String storeId, List skuIdList); + /// 期初入库 GaoProductStock initialIn(GaoProductStockChangeRequest request); diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductServiceImplement.java index 6ecef9d..e303c13 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductServiceImplement.java @@ -8,7 +8,9 @@ import com.imyeyu.api.modules.gao.entity.GaoProductCategory; import com.imyeyu.api.modules.gao.entity.GaoProductSpec; import com.imyeyu.api.modules.gao.entity.GaoProductSpecValue; import com.imyeyu.api.modules.gao.entity.GaoProductSku; +import com.imyeyu.api.modules.gao.entity.GaoProductStock; import com.imyeyu.api.modules.gao.mapper.GaoProductMapper; +import com.imyeyu.api.modules.gao.mapper.GaoProductStockMapper; import com.imyeyu.api.modules.gao.service.GaoProductCategoryService; import com.imyeyu.api.modules.gao.service.GaoProductService; import com.imyeyu.api.modules.gao.service.GaoProductSkuService; @@ -48,6 +50,7 @@ import java.util.stream.Collectors; public class GaoProductServiceImplement extends AbstractEntityService implements GaoProductService { private final GaoProductMapper mapper; + private final GaoProductStockMapper stockMapper; private final AttachmentService attachmentService; private final ObjectProvider categoryServiceProvider; private final ObjectProvider skuServiceProvider; @@ -120,6 +123,9 @@ public class GaoProductServiceImplement extends AbstractEntityService skuIdList = skuServiceProvider.getObject().listByProductId(product.getId()).stream() + .map(GaoProductSku::getId) + .filter(id -> id != null && !id.isBlank()) + .toList(); + if (skuIdList.isEmpty()) { + return; + } + boolean hasReservedStock = stockMapper.selectByStoreIdAndSkuIdList(product.getStoreId(), skuIdList).stream() + .anyMatch(stock -> stock.getReservedQuantity() != null && 0 < stock.getReservedQuantity().signum()); + TimiException.requiredTrue(!hasReservedStock, "当前产品存在预占库存,不能切换为服务产品,请先完成或取消相关订单"); + } + @OperationAudit(AuditOperation.GAO_PRODUCT_DISABLE) @Transactional(TimiServerDBConfig.ROLLBACKER) @Override diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductStockServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductStockServiceImplement.java index 740cb50..5cca2e0 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductStockServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoProductStockServiceImplement.java @@ -68,7 +68,8 @@ public class GaoProductStockServiceImplement implements GaoProductStockService { List list = stockMapper.selectByQuery(page); Map photoMap = attachmentService.mapFirstImageByIdList( Attachment.BizType.GAO_PRODUCT_SKU, - list.stream().map(GaoProductStock::getSkuId).filter(id -> id != null && !id.isBlank()).toList() + list.stream().map(GaoProductStock::getSkuId).filter(id -> id != null && !id.isBlank()).toList(), + "PHOTO" ); for (GaoProductStock stock : list) { fillBalance(stock); @@ -86,7 +87,17 @@ public class GaoProductStockServiceImplement implements GaoProductStockService { TimiException.required(page, "not found stock product page"); PageResult result = new PageResult<>(); result.setTotal(stockMapper.countProductByQuery(page)); - result.setList(stockMapper.selectProductByQuery(page)); + List list = stockMapper.selectProductByQuery(page); + Map photoMap = attachmentService.mapFirstImageByIdList( + Attachment.BizType.GAO_PRODUCT, + list.stream().map(GaoProductStockProductView::getProductId).filter(id -> id != null && !id.isBlank()).toList(), + "PHOTO" + ); + for (GaoProductStockProductView product : list) { + Attachment photo = photoMap.get(product.getProductId()); + product.setAttachmentList(photo == null ? List.of() : List.of(photo)); + } + result.setList(list); return result; } @@ -111,6 +122,27 @@ public class GaoProductStockServiceImplement implements GaoProductStockService { return stock; } + @Override + public List batchDetail(String storeId, List skuIdList) { + TimiException.required(storeId, "not found storeId"); + storeScopeService.checkStoreId(storeId); + if (skuIdList == null || skuIdList.isEmpty()) { + return List.of(); + } + List normalizedSkuIdList = skuIdList.stream() + .filter(value -> value != null && !value.isBlank()) + .distinct() + .toList(); + if (normalizedSkuIdList.isEmpty()) { + return List.of(); + } + List result = stockMapper.selectByStoreIdAndSkuIdList(storeId, normalizedSkuIdList); + for (GaoProductStock stock : result) { + fillBalance(stock); + } + return result; + } + @OperationAudit(AuditOperation.GAO_PRODUCT_STOCK_INITIAL_IN) @Transactional(TimiServerDBConfig.ROLLBACKER) @Override diff --git a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockBatchRequest.java b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockBatchRequest.java new file mode 100644 index 0000000..3a6e6d1 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockBatchRequest.java @@ -0,0 +1,19 @@ +package com.imyeyu.api.modules.gao.vo; + +import lombok.Data; + +import java.util.List; + +/// GAO 产品库存批量查询请求 +/// +/// @author Codex +/// @since 2026-09-16 +@Data +public class GaoProductStockBatchRequest { + + /// 门店 ID + private String storeId; + + /// SKU ID 列表 + private List skuIdList; +} diff --git a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockProductView.java b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockProductView.java index bb891d0..ed4ee30 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockProductView.java +++ b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoProductStockProductView.java @@ -1,9 +1,11 @@ package com.imyeyu.api.modules.gao.vo; +import com.imyeyu.api.modules.common.entity.Attachment; import com.imyeyu.api.modules.gao.entity.GaoProduct; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /// 产品库存第一层汇总视图 /// @@ -21,6 +23,9 @@ public class GaoProductStockProductView { /// 产品名称 private String productName; + /// 产品图片 + private List attachmentList; + /// 产品类型 private GaoProduct.ProductType productType; diff --git a/src/main/resources/mapper/timi-server/gao/GaoProductStockMapper.xml b/src/main/resources/mapper/timi-server/gao/GaoProductStockMapper.xml index 7a3a673..8da1e16 100644 --- a/src/main/resources/mapper/timi-server/gao/GaoProductStockMapper.xml +++ b/src/main/resources/mapper/timi-server/gao/GaoProductStockMapper.xml @@ -10,6 +10,25 @@ SELECT * FROM `gao_product_stock` WHERE `store_id` = #{storeId} AND `sku_id` = #{skuId} +