From d9c8cc478e2a1bc6f0356f88700dac405af17cd7 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 25 Aug 2026 11:54:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../baiyue/firstleg/BaiyueFirstlegApplication.java | 2 +- ...latformCustomerTransitStatisticsController.java | 6 +++--- .../CustomerTransitStatisticsMapper.java | 14 +++++--------- .../CustomerTransitStatisticsService.java | 10 +++++----- .../model}/CustomerTransitStatisticsDtos.java | 2 +- .../port/out/CustomerTransitStatisticsReader.java | 11 +++++++++++ .../BaiyueFirstlegApplicationContractTest.java | 3 ++- .../CustomerTransitStatisticsContractTest.java | 6 +++--- .../CustomerTransitStatisticsServiceTest.java | 10 +++++----- 9 files changed, 36 insertions(+), 28 deletions(-) rename firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/{controller => adapter/in/web}/PlatformCustomerTransitStatisticsController.java (83%) rename firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/{mapper => adapter/out/persistence}/CustomerTransitStatisticsMapper.java (85%) rename firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/{service => application}/CustomerTransitStatisticsService.java (75%) rename firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/{dto => application/model}/CustomerTransitStatisticsDtos.java (84%) create mode 100644 firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java diff --git a/firstleg/src/main/java/com/baiyue/firstleg/BaiyueFirstlegApplication.java b/firstleg/src/main/java/com/baiyue/firstleg/BaiyueFirstlegApplication.java index b9ed1c6ee..8c071e0be 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/BaiyueFirstlegApplication.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/BaiyueFirstlegApplication.java @@ -18,7 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; "com.baiyue.firstleg.outbound.dispatch.mapper", "com.baiyue.firstleg.portschedule.mapper", "com.baiyue.firstleg.customs.mapper", - "com.baiyue.firstleg.customerstatistics.mapper" + "com.baiyue.firstleg.customerstatistics.adapter.out.persistence" }) @EnableFeignClients(basePackages = "com.baiyue.firstleg") @EnableScheduling diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/controller/PlatformCustomerTransitStatisticsController.java b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/in/web/PlatformCustomerTransitStatisticsController.java similarity index 83% rename from firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/controller/PlatformCustomerTransitStatisticsController.java rename to firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/in/web/PlatformCustomerTransitStatisticsController.java index ca99b7399..ae441abed 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/controller/PlatformCustomerTransitStatisticsController.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/in/web/PlatformCustomerTransitStatisticsController.java @@ -1,9 +1,9 @@ -package com.baiyue.firstleg.customerstatistics.controller; +package com.baiyue.firstleg.customerstatistics.adapter.in.web; import com.baiyue.common.core.api.ApiResponse; import com.baiyue.common.security.AuthenticatedUser; -import com.baiyue.firstleg.customerstatistics.dto.CustomerTransitStatisticsDtos.TransitSummary; -import com.baiyue.firstleg.customerstatistics.service.CustomerTransitStatisticsService; +import com.baiyue.firstleg.customerstatistics.application.CustomerTransitStatisticsService; +import com.baiyue.firstleg.customerstatistics.application.model.CustomerTransitStatisticsDtos.TransitSummary; import com.baiyue.firstleg.service.FirstlegScopeGuard; import jakarta.annotation.Resource; import jakarta.validation.constraints.Positive; diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/mapper/CustomerTransitStatisticsMapper.java b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/out/persistence/CustomerTransitStatisticsMapper.java similarity index 85% rename from firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/mapper/CustomerTransitStatisticsMapper.java rename to firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/out/persistence/CustomerTransitStatisticsMapper.java index 0c208dc1e..93f276654 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/mapper/CustomerTransitStatisticsMapper.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/adapter/out/persistence/CustomerTransitStatisticsMapper.java @@ -1,14 +1,13 @@ -package com.baiyue.firstleg.customerstatistics.mapper; +package com.baiyue.firstleg.customerstatistics.adapter.out.persistence; +import com.baiyue.firstleg.customerstatistics.application.port.out.CustomerTransitStatisticsReader; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import java.math.BigDecimal; -import java.time.LocalDateTime; - @Mapper -public interface CustomerTransitStatisticsMapper { +public interface CustomerTransitStatisticsMapper extends CustomerTransitStatisticsReader { + @Override @Select(""" SELECT #{customerId} AS customerId, COUNT(*) AS containerCount, @@ -49,8 +48,5 @@ public interface CustomerTransitStatisticsMapper { WHERE x.customer_id = #{customerId} ) scoped """) - SummaryRow summarize(@Param("customerId") long customerId); - - record SummaryRow(Long customerId, Long containerCount, BigDecimal totalTeu, - Long unknownContainerCount, LocalDateTime asOf) {} + SummaryProjection summarize(@Param("customerId") long customerId); } diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/service/CustomerTransitStatisticsService.java b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/CustomerTransitStatisticsService.java similarity index 75% rename from firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/service/CustomerTransitStatisticsService.java rename to firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/CustomerTransitStatisticsService.java index 485a9572b..71477ce5b 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/service/CustomerTransitStatisticsService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/CustomerTransitStatisticsService.java @@ -1,9 +1,9 @@ -package com.baiyue.firstleg.customerstatistics.service; +package com.baiyue.firstleg.customerstatistics.application; import com.baiyue.common.core.api.ResultCode; import com.baiyue.common.core.exception.BizException; -import com.baiyue.firstleg.customerstatistics.dto.CustomerTransitStatisticsDtos.TransitSummary; -import com.baiyue.firstleg.customerstatistics.mapper.CustomerTransitStatisticsMapper; +import com.baiyue.firstleg.customerstatistics.application.model.CustomerTransitStatisticsDtos.TransitSummary; +import com.baiyue.firstleg.customerstatistics.application.port.out.CustomerTransitStatisticsReader; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -12,11 +12,11 @@ import java.math.BigDecimal; @Service public class CustomerTransitStatisticsService { private static final String DEFINITION = "actual_sailing_at IS NOT NULL 且 actual_warehouse_arrival_at IS NULL;排除取消/失败订舱;客户+containerBookingId去重;拼柜按active LoadingPlanItem.accountId归属,整柜按OceanBooking.customerId归属。TEU:20*=1,40*=2,45*=2.25,未知箱型不计totalTeu。"; - @Resource private CustomerTransitStatisticsMapper mapper; + @Resource private CustomerTransitStatisticsReader reader; public TransitSummary summarize(long customerId) { if (customerId <= 0) throw new BizException(ResultCode.BAD_REQUEST, "customerId必须为正数"); - var row = mapper.summarize(customerId); + var row = reader.summarize(customerId); return new TransitSummary(customerId, value(row == null ? null : row.containerCount()), row == null || row.totalTeu() == null ? BigDecimal.ZERO : row.totalTeu(), diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/dto/CustomerTransitStatisticsDtos.java b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/model/CustomerTransitStatisticsDtos.java similarity index 84% rename from firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/dto/CustomerTransitStatisticsDtos.java rename to firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/model/CustomerTransitStatisticsDtos.java index e123871da..7afb319b1 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/dto/CustomerTransitStatisticsDtos.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/model/CustomerTransitStatisticsDtos.java @@ -1,4 +1,4 @@ -package com.baiyue.firstleg.customerstatistics.dto; +package com.baiyue.firstleg.customerstatistics.application.model; import java.math.BigDecimal; import java.time.LocalDateTime; diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java new file mode 100644 index 000000000..58ece2751 --- /dev/null +++ b/firstleg/src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java @@ -0,0 +1,11 @@ +package com.baiyue.firstleg.customerstatistics.application.port.out; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +public interface CustomerTransitStatisticsReader { + SummaryProjection summarize(long customerId); + + record SummaryProjection(Long customerId, Long containerCount, BigDecimal totalTeu, + Long unknownContainerCount, LocalDateTime asOf) {} +} diff --git a/firstleg/src/test/java/com/baiyue/firstleg/BaiyueFirstlegApplicationContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/BaiyueFirstlegApplicationContractTest.java index 30474a894..2b9409161 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/BaiyueFirstlegApplicationContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/BaiyueFirstlegApplicationContractTest.java @@ -20,7 +20,8 @@ class BaiyueFirstlegApplicationContractTest { .contains("com.baiyue.firstleg.outbound.dispatch.mapper") .contains("com.baiyue.firstleg.portschedule.mapper") .contains("com.baiyue.firstleg.customs.mapper") - .contains("com.baiyue.firstleg.customerstatistics.mapper"); + .contains("com.baiyue.firstleg.customerstatistics.adapter.out.persistence") + .doesNotContain("com.baiyue.firstleg.customerstatistics.mapper"); } @Test diff --git a/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsContractTest.java index 33463262f..33793badc 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsContractTest.java @@ -1,8 +1,8 @@ package com.baiyue.firstleg.customerstatistics; -import com.baiyue.firstleg.customerstatistics.controller.PlatformCustomerTransitStatisticsController; -import com.baiyue.firstleg.customerstatistics.mapper.CustomerTransitStatisticsMapper; -import com.baiyue.firstleg.customerstatistics.service.CustomerTransitStatisticsService; +import com.baiyue.firstleg.customerstatistics.adapter.in.web.PlatformCustomerTransitStatisticsController; +import com.baiyue.firstleg.customerstatistics.adapter.out.persistence.CustomerTransitStatisticsMapper; +import com.baiyue.firstleg.customerstatistics.application.CustomerTransitStatisticsService; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsServiceTest.java index e7028ebb9..04bf83ec8 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/customerstatistics/CustomerTransitStatisticsServiceTest.java @@ -1,8 +1,8 @@ package com.baiyue.firstleg.customerstatistics; import com.baiyue.common.core.exception.BizException; -import com.baiyue.firstleg.customerstatistics.mapper.CustomerTransitStatisticsMapper; -import com.baiyue.firstleg.customerstatistics.service.CustomerTransitStatisticsService; +import com.baiyue.firstleg.customerstatistics.application.CustomerTransitStatisticsService; +import com.baiyue.firstleg.customerstatistics.application.port.out.CustomerTransitStatisticsReader; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -19,12 +19,12 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class CustomerTransitStatisticsServiceTest { - @Mock CustomerTransitStatisticsMapper mapper; + @Mock CustomerTransitStatisticsReader reader; @InjectMocks CustomerTransitStatisticsService service; @Test void preservesDecimalTeuAndUnknownCount() { var asOf = LocalDateTime.of(2026, 8, 13, 12, 0); - when(mapper.summarize(88L)).thenReturn(new CustomerTransitStatisticsMapper.SummaryRow( + when(reader.summarize(88L)).thenReturn(new CustomerTransitStatisticsReader.SummaryProjection( 88L, 4L, new BigDecimal("6.25"), 1L, asOf)); var result = service.summarize(88L); @@ -35,7 +35,7 @@ class CustomerTransitStatisticsServiceTest { assertThat(result.unknownContainerCount()).isEqualTo(1); assertThat(result.asOf()).isEqualTo(asOf); assertThat(result.definition()).contains("20*=1", "40*=2", "45*=2.25", "未知箱型"); - verify(mapper).summarize(88L); + verify(reader).summarize(88L); } @Test void rejectsInvalidCustomerBeforeQuery() {