From a4abdc0632054634f4f498f0bbc0af4d72a56a5a Mon Sep 17 00:00:00 2001 From: Timi Date: Fri, 16 Oct 2026 00:22:37 +0800 Subject: [PATCH] add GaoPointRedeemSkuPageResult --- .../GaoPointRedeemSkuController.java | 8 ++++-- .../gao/mapper/GaoPointRedemptionMapper.java | 9 +++++++ .../gao/service/GaoPointRedeemSkuService.java | 9 ++++--- .../GaoOrderFulfillmentServiceImplement.java | 22 +++++++++++++--- .../GaoPointRedeemSkuServiceImplement.java | 16 +++++++++--- .../GaoProductStockServiceImplement.java | 2 ++ .../gao/vo/GaoPointRedeemSkuPageResult.java | 26 +++++++++++++++++++ .../gao/GaoPointRedemptionMapper.xml | 15 +++++++++++ 8 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedeemSkuPageResult.java diff --git a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPointRedeemSkuController.java b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPointRedeemSkuController.java index 3fa56dd..7f583b3 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPointRedeemSkuController.java +++ b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoPointRedeemSkuController.java @@ -6,11 +6,11 @@ import com.imyeyu.api.modules.gao.entity.GaoPointRedeemSku; import com.imyeyu.api.modules.gao.service.GaoPointRedeemSkuService; import com.imyeyu.api.modules.gao.service.GaoStoreScopeService; import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuPage; +import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuPageResult; import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuRequest; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; -import com.imyeyu.spring.bean.PageResult; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -30,11 +30,15 @@ public class GaoPointRedeemSkuController { private final GaoPointRedeemSkuService service; private final GaoStoreScopeService storeScopeService; + /// 分页查询兑换 SKU 配置,指定 SKU 时附带基础单位兑换统计 + /// @param page 分页与筛选条件 + /// @return 兑换 SKU 分页结果,指定 SKU 时包含基础单位兑换统计 + /// @throws TimiException 分页条件为空 @AOPLog @RequestRateLimit @RequireGaoPermission(GaoPermissionCode.POINT_REDEEM_SKU_MANAGE) @PostMapping("/list") - public PageResult list(@RequestBody GaoPointRedeemSkuPage page) { + public GaoPointRedeemSkuPageResult list(@RequestBody GaoPointRedeemSkuPage page) { TimiException.required(page, "not found redeem sku page"); page.setStoreId(storeScopeService.resolveStoreId(page.getStoreId())); return service.pageByQuery(page); diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointRedemptionMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointRedemptionMapper.java index e75f5e0..d2c9e3f 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointRedemptionMapper.java +++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointRedemptionMapper.java @@ -2,6 +2,7 @@ package com.imyeyu.api.modules.gao.mapper; import com.imyeyu.api.modules.gao.entity.GaoPointRedemption; import com.imyeyu.api.modules.gao.vo.GaoPointRedemptionPage; +import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuPageResult; import com.imyeyu.spring.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; @@ -32,4 +33,12 @@ public interface GaoPointRedemptionMapper extends BaseMapper pageByQuery(GaoPointRedeemSkuPage page); + /// 分页查询兑换 SKU 配置,指定 SKU 时附带基础单位兑换统计 + /// @param page 分页与筛选条件 + /// @return 兑换 SKU 分页结果,指定 SKU 时包含基础单位兑换统计 + /// @throws TimiException 分页条件为空 + GaoPointRedeemSkuPageResult pageByQuery(GaoPointRedeemSkuPage page); /// 查询兑换 SKU 配置详情 GaoPointRedeemSku detail(String storeId, String id); diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoOrderFulfillmentServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoOrderFulfillmentServiceImplement.java index b4c032f..5e25797 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoOrderFulfillmentServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoOrderFulfillmentServiceImplement.java @@ -168,18 +168,19 @@ public class GaoOrderFulfillmentServiceImplement extends AbstractEntityService requestItems = filterZeroQuantityItems(request.getItemList()); String requestNo = requiredText(request.getRequestNo(), "not found requestNo"); TimiException.required(request.getSalesOrderId(), "not found salesOrderId"); GaoSalesOrder order = salesOrderService.getForUpdate(request.getSalesOrderId()); GaoOrderFulfillment existing = mapper.selectByRequestNo(order.getStoreId(), requestNo); if (existing != null) { - verifyIdempotency(existing, request); + verifyIdempotency(existing, request, requestItems); return detail(existing.getId()); } TimiException.requiredTrue(hasAttachment(request.getAttachmentList()), "履约必须上传照片"); TimiException.requiredTrue(order.getStatus() != GaoSalesOrder.Status.CANCELLED, "已取消订单不能履约"); salesOrderService.checkFulfillmentPermission(order); - List sourceList = loadSources(order, request.getItemList(), true); + List sourceList = loadSources(order, requestItems, true); List stockItems = buildStockItems(order.getStoreId(), sourceList); boolean stockReady = stockItems.isEmpty() || productStockService.hasSufficientForFulfillment(order.getStoreId(), stockItems); String operatorUserId = userLoginService.getRequireLoginUserId(); @@ -443,6 +444,19 @@ public class GaoOrderFulfillmentServiceImplement extends AbstractEntityService filterZeroQuantityItems(List requestItems) { + if (requestItems == null) { + return null; + } + return requestItems.stream() + .filter(item -> item == null || item.getQuantity() == null || 0 != item.getQuantity().signum()) + .toList(); + } + private List loadSources(GaoSalesOrder order, List requestItems, boolean checkAvailable) { TimiException.requiredTrue(requestItems != null && !requestItems.isEmpty(), "履约至少需要一个产品"); List sortedRequestItems = new ArrayList<>(requestItems); @@ -657,12 +671,12 @@ public class GaoOrderFulfillmentServiceImplement extends AbstractEntityService requestItems) { TimiException.requiredTrue(existing.getSalesOrderId().equals(request.getSalesOrderId()) && (request.getDeliveredAt() == null || request.getDeliveredAt().equals(existing.getDeliveredAt())) && sameText(existing.getRemark(), request.getRemark()), "requestNo 对应履约请求内容不一致"); List existingItems = itemMapper.selectByFulfillmentId(existing.getId()); - List requestItems = request.getItemList(); TimiException.requiredTrue(existingItems.size() == (requestItems == null ? 0 : requestItems.size()), "requestNo 对应履约请求内容不一致"); Map requestMap = new HashMap<>(); for (GaoOrderFulfillmentItemRequest item : TimiJava.safeIterable(requestItems)) { diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointRedeemSkuServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointRedeemSkuServiceImplement.java index 06bed54..8b1f965 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointRedeemSkuServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointRedeemSkuServiceImplement.java @@ -5,16 +5,17 @@ import com.imyeyu.api.modules.gao.entity.GaoProduct; import com.imyeyu.api.modules.gao.entity.GaoProductSku; import com.imyeyu.api.modules.gao.entity.GaoProductSkuUnit; import com.imyeyu.api.modules.gao.entity.GaoPointRedeemSku; +import com.imyeyu.api.modules.gao.mapper.GaoPointRedemptionMapper; import com.imyeyu.api.modules.gao.mapper.GaoPointRedeemSkuMapper; import com.imyeyu.api.modules.gao.service.GaoPointRedeemSkuService; import com.imyeyu.api.modules.gao.service.GaoProductService; import com.imyeyu.api.modules.gao.service.GaoProductSkuService; import com.imyeyu.api.modules.gao.service.GaoStoreScopeService; import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuPage; +import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuPageResult; import com.imyeyu.api.modules.gao.vo.GaoPointRedeemSkuRequest; import com.imyeyu.java.TimiJava; import com.imyeyu.java.bean.timi.TimiException; -import com.imyeyu.spring.bean.PageResult; import com.imyeyu.utils.Time; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -35,15 +36,24 @@ import java.util.UUID; public class GaoPointRedeemSkuServiceImplement implements GaoPointRedeemSkuService { private final GaoPointRedeemSkuMapper mapper; + private final GaoPointRedemptionMapper redemptionMapper; private final GaoProductService productService; private final GaoProductSkuService skuService; private final GaoStoreScopeService storeScopeService; @Override - public PageResult pageByQuery(GaoPointRedeemSkuPage page) { + public GaoPointRedeemSkuPageResult pageByQuery(GaoPointRedeemSkuPage page) { TimiException.required(page, "not found redeem sku page"); - PageResult result = new PageResult<>(); + GaoPointRedeemSkuPageResult result = new GaoPointRedeemSkuPageResult(); result.setTotal(mapper.countByQuery(page)); + if (page.getSkuId() != null && !page.getSkuId().isBlank()) { + GaoPointRedeemSkuPageResult summary = redemptionMapper.selectSkuSummaryByStoreIdAndSkuId( + page.getStoreId(), page.getSkuId() + ); + result.setRedeemedBaseQuantityTotal(summary.getRedeemedBaseQuantityTotal()); + result.setReturnedBaseQuantityTotal(summary.getReturnedBaseQuantityTotal()); + result.setNetRedeemedBaseQuantityTotal(summary.getNetRedeemedBaseQuantityTotal()); + } List list = mapper.selectByQuery(page); fillTransient(list); result.setList(list); 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 66bf138..9852e24 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 @@ -182,6 +182,8 @@ public class GaoProductStockServiceImplement implements GaoProductStockService { TimiException.requiredTrue(hasText(remark), "库存操作必须填写备注"); TimiException.requiredTrue(request.getItemList() != null && !request.getItemList().isEmpty(), "批量入库至少需要一个 SKU"); List requestItemList = new ArrayList<>(request.getItemList()); + requestItemList.removeIf(item -> item != null && item.getQuantity() != null && item.getQuantity().signum() == 0); + TimiException.requiredTrue(!requestItemList.isEmpty(), "批量入库至少需要一个正数量 SKU"); for (GaoProductStockManualInBatchRequest.Item item : requestItemList) { TimiException.required(item, "库存变更项不能为空"); item.setSkuId(requiredText(item.getSkuId(), "not found skuId")); diff --git a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedeemSkuPageResult.java b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedeemSkuPageResult.java new file mode 100644 index 0000000..188a416 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedeemSkuPageResult.java @@ -0,0 +1,26 @@ +package com.imyeyu.api.modules.gao.vo; + +import com.imyeyu.api.modules.gao.entity.GaoPointRedeemSku; +import com.imyeyu.spring.bean.PageResult; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/// GAO 积分兑换 SKU 配置分页查询结果 +/// +/// @author Codex +/// @since 2026-10-15 +@Data +@EqualsAndHashCode(callSuper = true) +public class GaoPointRedeemSkuPageResult extends PageResult { + + /// SKU 筛选条件下的累计兑换基础数量 + private BigDecimal redeemedBaseQuantityTotal; + + /// SKU 筛选条件下的累计退货基础数量 + private BigDecimal returnedBaseQuantityTotal; + + /// SKU 筛选条件下的净兑换基础数量 + private BigDecimal netRedeemedBaseQuantityTotal; +} diff --git a/src/main/resources/mapper/timi-server/gao/GaoPointRedemptionMapper.xml b/src/main/resources/mapper/timi-server/gao/GaoPointRedemptionMapper.xml index 6e51f3c..f333a99 100644 --- a/src/main/resources/mapper/timi-server/gao/GaoPointRedemptionMapper.xml +++ b/src/main/resources/mapper/timi-server/gao/GaoPointRedemptionMapper.xml @@ -63,4 +63,19 @@ AND `redeemed_at` >= #{beginAt} AND `redeemed_at` <= #{endAt} +