From ec8e8f1c208abe54042add2124c9759d9b1369d1 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 12 九月 2026 16:59:06 +0800
Subject: [PATCH] feat(order): 核销幂等与退款边界按订单串行化
---
talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationOrderCodeTests.java | 34 ++++++++++++++++++++++++++++------
1 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationOrderCodeTests.java b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationOrderCodeTests.java
index 9311959..efdc50f 100644
--- a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationOrderCodeTests.java
+++ b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationOrderCodeTests.java
@@ -12,11 +12,14 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.transaction.support.TransactionTemplate;
class MerchantVerificationOrderCodeTests {
private JdbcTemplate jdbc;
+ private TransactionTemplate transactions;
private MerchantVerificationService service;
private MerchantPrincipal principal;
@@ -26,6 +29,7 @@
"jdbc:h2:mem:order-code-verification-" + System.nanoTime()
+ ";MODE=MySQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1", "sa", "");
jdbc = new JdbcTemplate(dataSource);
+ transactions = new TransactionTemplate(new DataSourceTransactionManager(dataSource));
jdbc.execute("""
create table merchant_verification_attempt (
id bigint auto_increment primary key,
@@ -55,6 +59,8 @@
pay_amount bigint not null,
order_status tinyint not null,
verify_status tinyint not null,
+ refund_status tinyint not null default 0,
+ withdrawal_status tinyint not null default 0,
merchant_id bigint not null,
store_id bigint,
deleted tinyint not null default 0
@@ -87,7 +93,8 @@
remark varchar(255)
)
""");
- service = new MerchantVerificationService(jdbc, new ManualConsumptionService(jdbc, null));
+ service = new MerchantVerificationService(jdbc, new ManualConsumptionService(jdbc, null),
+ new com.talentcard.server.business.order.OrderFundBoundaryService(jdbc));
principal = new MerchantPrincipal(9L, 88L, 7L, "operator");
}
@@ -95,8 +102,7 @@
void confirmsGroupOrderAfterScannedCodeExpiresAndRefreshes() {
insertOrder("expired-group-order", 1);
- Map<String, Object> confirmed = service.confirm(principal,
- new VerificationConfirmRequest("expired-group-order"), "order-confirm-expired-group-order");
+ Map<String, Object> confirmed = confirm("expired-group-order");
assertThat(confirmed.get("verified")).isEqualTo(true);
assertThat(jdbc.queryForObject("select status from order_dynamic_verification_code where id = 30", Integer.class)).isEqualTo(1);
@@ -110,10 +116,26 @@
void stillRejectsUnpaidGroupOrder() {
insertOrder("unpaid-group-order", 0);
- assertThatThrownBy(() -> service.confirm(principal, new VerificationConfirmRequest("unpaid-group-order"),
- "order-confirm-unpaid-group-order"))
+ assertThatThrownBy(() -> confirm("unpaid-group-order"))
.isInstanceOf(BusinessException.class)
- .hasMessageContaining("当前不可核销");
+ .hasMessageContaining("未支付");
+ }
+
+ @Test
+ void rejectsGroupOrderThatWasRefundedWhileTheCodeWasOpen() {
+ insertOrder("refunded-group-order", 1);
+ jdbc.update("update benefit_order set refund_status = 2 where id = 20");
+
+ assertThatThrownBy(() -> confirm("refunded-group-order"))
+ .isInstanceOf(BusinessException.class)
+ .hasMessageContaining("退款");
+ assertThat(jdbc.queryForObject("select verify_status from benefit_order where id = 20", Integer.class)).isZero();
+ }
+
+ /** 核销确认按订单行锁串行化,所以测试也必须在一个真实事务里调用它。 */
+ private Map<String, Object> confirm(String verificationId) {
+ return transactions.execute(status -> service.confirm(principal,
+ new VerificationConfirmRequest(verificationId), "order-confirm-" + verificationId));
}
private void insertOrder(String verificationId, int orderStatus) {
--
Gitblit v1.7.1