From c5a63165aca6468157e0b4807d511e828de2076a Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期三, 16 九月 2026 16:07:33 +0800
Subject: [PATCH] 再次更新

---
 talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java |  221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 220 insertions(+), 1 deletions(-)

diff --git a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java
index db4f58d..ff21dd1 100644
--- a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java
+++ b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/ManualConsumptionServiceTests.java
@@ -1,6 +1,7 @@
 package com.talentcard.server.business.merchant;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.math.BigDecimal;
 import java.util.LinkedHashMap;
@@ -9,6 +10,8 @@
 import com.talentcard.server.business.merchant.auth.MerchantPrincipal;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.datasource.DriverManagerDataSource;
 
@@ -21,7 +24,7 @@
     @BeforeEach
     void setUp() {
         DriverManagerDataSource dataSource = new DriverManagerDataSource(
-                "jdbc:h2:mem:manual-consumption-" + System.nanoTime() + ";MODE=MySQL;DB_CLOSE_DELAY=-1", "sa", "");
+                "jdbc:h2:mem:manual-consumption-" + System.nanoTime() + ";MODE=MySQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1", "sa", "");
         jdbc = new JdbcTemplate(dataSource);
         jdbc.execute("""
                 create table talent_dynamic_code (
@@ -34,6 +37,7 @@
         jdbc.execute("""
                 create table merchant (
                     id bigint primary key,
+                    merchant_type_code varchar(64),
                     merchant_rights_config varchar(4000),
                     deleted tinyint not null default 0
                 )
@@ -84,6 +88,221 @@
         assertThat(service.configuredStoreConsumptionEnabled(right)).isTrue();
         right.put("parkingType", "free");
         assertThat(service.configuredStoreConsumptionEnabled(right)).isFalse();
+        right.put("consumeEnabled", true);
+        assertThat(service.configuredStoreConsumptionEnabled(right)).isFalse();
+    }
+
+    @Test
+    void paidParkingUsesParkingDiscountInsteadOfUnrelatedConsumeFields() {
+        Map<String, Object> right = configuredRight("卓越人才卡", "6");
+        right.put("parkingType", "paid");
+        right.put("consumeType", "优惠");
+        right.put("consumeCoupon", "8");
+        right.put("consumeDiscount", "9");
+        Map<String, Object> rule = service.configuredRule(right);
+        assertThat(rule).containsEntry("benefitText", "到店消费6折");
+        assertThat(service.quote(rule, null, new BigDecimal("10")))
+                .containsEntry("payAmount", 600L).containsEntry("discountAmount", 400L);
+        right.put("consumeType", "折扣");
+        assertThat(service.configuredRule(right)).containsEntry("benefitText", "到店消费6折");
+    }
+
+    @Test
+    void parkingDedicatedRightsOverrideLegacyAndRespectDisabledAndFreeLevels() {
+        jdbc.execute("""
+                create table transport_parking_card_level_right (
+                    merchant_id bigint, card_level varchar(64), enabled tinyint, label varchar(128),
+                    benefit_detail varchar(500), charge_type varchar(32), store_consume_enabled tinyint,
+                    discount_text varchar(64), government_subsidy tinyint, consume_usage_text varchar(500),
+                    status tinyint, deleted tinyint default 0
+                )
+                """);
+        jdbc.update("insert into merchant(id, merchant_type_code, merchant_rights_config) values (88, 'parking', null)");
+        jdbc.update("""
+                insert into transport_parking_card_level_right
+                    (merchant_id, card_level, enabled, charge_type, store_consume_enabled, discount_text, status)
+                values (88, '卓越人才卡', 1, 'PAID', 1, '6折', 1)
+                """);
+        assertThat(service.hasApplicableRule(88L, "EXCELLENT", "")).isTrue();
+        assertThat(service.hasApplicableRule(88L, "杰出人才卡", "")).isFalse();
+        assertParkingDetailAndQuote();
+        jdbc.update("update merchant set merchant_rights_config = ? where id = 88",
+                "[{\"level\":\"卓越人才卡\",\"enabled\":true,\"storeConsume\":true,\"consumeEnabled\":true,\"parkingType\":\"paid\",\"discount\":\"9\"}]");
+        jdbc.update("update transport_parking_card_level_right set status = 0");
+        assertThat(service.hasApplicableRule(88L, "卓越人才卡", "")).isFalse();
+        jdbc.update("update transport_parking_card_level_right set status = 1, charge_type = 'FREE'");
+        assertThat(service.hasApplicableRule(88L, "卓越人才卡", "")).isFalse();
+        jdbc.update("update transport_parking_card_level_right set charge_type = 'PAID', store_consume_enabled = 0");
+        assertThat(service.hasApplicableRule(88L, "卓越人才卡", "")).isFalse();
+    }
+
+    private void assertParkingDetailAndQuote() {
+        prepareConsumptionDetail();
+        for (String discount : new String[] {"6折", "7折", "10折"}) {
+            jdbc.update("update transport_parking_card_level_right set discount_text = ?", discount);
+            Map<String, Object> detail = service.detail(principal, "parking-scan");
+            assertThat(detail).containsEntry("cardLevel", "卓越人才卡");
+            java.util.List<?> rules = (java.util.List<?>) detail.get("rules");
+            assertThat(rules).hasSize(1);
+            Map<?, ?> rule = (Map<?, ?>) rules.get(0);
+            assertThat(rule.get("benefitText")).isEqualTo("到店消费" + discount);
+            Map<String, Object> quote = service.quote(principal, new ManualConsumptionCreateRequest(
+                    "parking-scan", ((Number) rule.get("id")).longValue(), new BigDecimal("10")));
+            assertThat(quote.get("payAmount")).isEqualTo(Long.parseLong(discount.replace("折", "")) * 100);
+        }
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"carWash", "dental"})
+    void merchantUsesEachScannedCardLevelDiscountInsteadOfItsLabel(String merchantType) {
+        prepareConsumptionDetail();
+        String[] levels = {"卓越人才卡", "杰出人才卡", "菁英人才卡"};
+        String[] discounts = {"7", "8.5", "9"};
+        java.util.List<Map<String, Object>> rights = new java.util.ArrayList<>();
+        for (int index = 0; index < levels.length; index++) {
+            Map<String, Object> right = configuredRight(levels[index], discounts[index]);
+            right.put("tag", levels[index] + "到店消费可用");
+            right.put("enabled", true);
+            right.put("storeConsume", true);
+            right.put("consumeEnabled", true);
+            rights.add(right);
+        }
+        jdbc.update("insert into merchant(id, merchant_type_code, merchant_rights_config) values (88, ?, ?)",
+                merchantType, com.alibaba.fastjson.JSON.toJSONString(rights));
+        for (int index = 0; index < levels.length; index++) {
+            jdbc.update("update talent_card set card_level = ? where id = 1", levels[index]);
+            Map<String, Object> detail = service.detail(principal, "parking-scan");
+            assertThat(detail).containsEntry("cardLevel", levels[index]);
+            java.util.List<?> rules = (java.util.List<?>) detail.get("rules");
+            assertThat(rules).hasSize(1);
+            Map<?, ?> rule = (Map<?, ?>) rules.get(0);
+            assertThat(rule.get("benefitText")).isEqualTo("到店消费" + discounts[index] + "折");
+            Map<String, Object> quote = service.quote(principal, new ManualConsumptionCreateRequest(
+                    "parking-scan", ((Number) rule.get("id")).longValue(), new BigDecimal("100")));
+            assertThat(quote.get("payAmount")).isEqualTo(new BigDecimal(discounts[index]).multiply(new BigDecimal("1000")).longValue());
+        }
+    }
+
+    private void prepareConsumptionDetail() {
+        jdbc.execute("alter table talent_dynamic_code add column talent_id bigint");
+        jdbc.execute("alter table talent_dynamic_code add column card_id bigint");
+        jdbc.execute("""
+                create table merchant_verification_attempt (
+                    id bigint, dynamic_code_id bigint, status tinyint, expires_at timestamp, manual_order_id bigint,
+                    verification_id varchar(64), credential_type varchar(64), merchant_id bigint, store_id bigint, operator_id bigint
+                )
+                """);
+        jdbc.execute("create table talent_card (id bigint, card_level varchar(64), deleted tinyint)");
+        jdbc.execute("create table talent_user (id bigint, name varchar(64), mobile varchar(32), gender tinyint, source_area_type varchar(32), deleted tinyint)");
+        jdbc.execute("create table merchant_card_benefit (id bigint, merchant_id bigint, card_level varchar(64), benefit_text varchar(500), status tinyint, sort_no int)");
+        jdbc.execute("""
+                create table merchant_coupon (
+                    id bigint, merchant_id bigint, coupon_name varchar(64), coupon_type varchar(64), coupon_amount decimal,
+                    talent_levels varchar(64), condition_type varchar(64), condition_amount decimal,
+                    valid_start date, valid_end date, deleted tinyint, status tinyint, store_consume tinyint
+                )
+                """);
+        jdbc.execute("create table benefit_order (coupon_id bigint, talent_id bigint, deleted tinyint, order_status tinyint, expires_at timestamp)");
+        jdbc.update("insert into talent_dynamic_code(id, status, talent_id, card_id) values (1, 0, 1, 1)");
+        jdbc.update("insert into talent_card values (1, '卓越人才卡', 0)");
+        jdbc.update("insert into talent_user values (1, '测试', '13800000000', 1, 'LOCAL', 0)");
+        jdbc.update("insert into merchant_verification_attempt values (1, 1, 0, null, null, 'parking-scan', 'TALENT_CODE', 88, 7, 9)");
+    }
+
+    @Test
+    void cultureHidesLegacyCouponsAndRejectsCouponQuotesAndOrders() {
+        prepareConsumptionDetail();
+        Map<String, Object> right = configuredRight("卓越人才卡", "8");
+        right.put("enabled", true);
+        right.put("storeConsume", true);
+        right.put("consumeEnabled", true);
+        jdbc.update("insert into merchant(id, merchant_type_code, merchant_rights_config) values (88, 'culture', ?)",
+                com.alibaba.fastjson.JSON.toJSONString(java.util.List.of(right)));
+        jdbc.update("""
+                insert into merchant_coupon (id, merchant_id, coupon_name, coupon_amount, talent_levels,
+                    condition_type, deleted, status, store_consume)
+                values (1, 88, '旧优惠券', 20, '卓越人才卡', 'NONE', 0, 1, 1)
+                """);
+        Map<String, Object> detail = service.detail(principal, "parking-scan");
+        assertThat((java.util.List<?>) detail.get("coupons")).isEmpty();
+        ManualConsumptionCreateRequest discountOnly = new ManualConsumptionCreateRequest("parking-scan", -1L, new BigDecimal("100"));
+        assertThat(service.quote(principal, discountOnly)).containsEntry("payAmount", 8000L).containsEntry("couponAmount", 0L);
+        ManualConsumptionCreateRequest withCoupon = new ManualConsumptionCreateRequest("parking-scan", -1L, new BigDecimal("100"), 1L);
+        assertThatThrownBy(() -> service.quote(principal, withCoupon))
+                .isInstanceOf(com.talentcard.server.common.BusinessException.class).hasMessageContaining("不支持优惠券");
+        assertThatThrownBy(() -> service.create(principal, withCoupon, "culture-coupon-test"))
+                .isInstanceOf(com.talentcard.server.common.BusinessException.class).hasMessageContaining("不支持优惠券");
+        assertThat(jdbc.queryForObject("select status from talent_dynamic_code where id = 1", Integer.class)).isZero();
+        assertThat(jdbc.queryForObject("select count(*) from benefit_order", Integer.class)).isZero();
+
+        jdbc.update("update merchant set merchant_type_code = 'food' where id = 88");
+        assertThat((java.util.List<?>) service.detail(principal, "parking-scan").get("coupons")).hasSize(1);
+        assertThat(service.quote(principal, withCoupon)).containsEntry("payAmount", 6000L).containsEntry("couponAmount", 2000L);
+    }
+
+    @Test
+    void cultureCurrentBenefitUsesOnlyTheScannedLevelsStoreConsumptionDescription() {
+        prepareConsumptionDetail();
+        String[] levels = {"卓越人才卡", "杰出人才卡", "菁英人才卡"};
+        java.util.List<Map<String, Object>> rights = new java.util.ArrayList<>();
+        for (String level : levels) {
+            Map<String, Object> right = configuredRight(level, "8");
+            right.put("enabled", true);
+            right.put("storeConsume", true);
+            right.put("consumeEnabled", true);
+            right.put("detail", "其他权益详情");
+            right.put("consumeDesc", level + "到店消费权益\n第二行  保留空格");
+            rights.add(right);
+        }
+        jdbc.update("insert into merchant(id, merchant_type_code, merchant_rights_config) values (88, 'culture', ?)",
+                com.alibaba.fastjson.JSON.toJSONString(rights));
+        jdbc.update("insert into merchant_card_benefit values (1, 88, 'EXCELLENT', '旧权益文案', 1, 0)");
+        for (String level : levels) {
+            jdbc.update("update talent_card set card_level = ? where id = 1", level);
+            String expected = level + "到店消费权益\n第二行  保留空格";
+            assertThat(service.detail(principal, "parking-scan"))
+                    .containsEntry("cardLevel", level).containsEntry("benefitText", expected);
+            assertThat(service.benefitTextForMerchant(88L, level)).isEqualTo(expected);
+        }
+        rights.get(0).put("consumeDesc", "");
+        rights.get(1).put("enabled", false);
+        jdbc.update("update merchant set merchant_rights_config = ? where id = 88", com.alibaba.fastjson.JSON.toJSONString(rights));
+        assertThat(service.benefitTextForMerchant(88L, levels[0])).isEmpty();
+        assertThat(service.benefitTextForMerchant(88L, levels[1])).isEmpty();
+        assertThat(service.benefitTextForMerchant(88L, "普通游客")).isEmpty();
+    }
+
+    @Test
+    void childcareCurrentBenefitUsesTheScannedLevelsRightsDescription() {
+        prepareConsumptionDetail();
+        String[] levels = {"卓越人才卡", "杰出人才卡", "菁英人才卡"};
+        java.util.List<Map<String, Object>> rights = new java.util.ArrayList<>();
+        for (String level : levels) {
+            Map<String, Object> right = configuredRight(level, "8");
+            right.put("enabled", true);
+            right.put("storeConsume", true);
+            right.put("consumeEnabled", true);
+            right.put("detail", level + "托管权益描述\n第二行内容");
+            right.put("consumeDesc", "不同的到店消费使用说明");
+            rights.add(right);
+        }
+        jdbc.update("insert into merchant(id, merchant_type_code, merchant_rights_config) values (88, 'children', ?)",
+                com.alibaba.fastjson.JSON.toJSONString(rights));
+        jdbc.update("insert into merchant_card_benefit values (1, 88, 'EXCELLENT', '旧权益文案', 1, 0)");
+        for (String level : levels) {
+            jdbc.update("update talent_card set card_level = ? where id = 1", level);
+            assertThat(service.detail(principal, "parking-scan"))
+                    .containsEntry("cardLevel", level)
+                    .containsEntry("benefitText", level + "托管权益描述\n第二行内容");
+            assertThat(service.benefitTextForMerchant(88L, level)).isEqualTo(level + "托管权益描述\n第二行内容");
+        }
+
+        rights.get(0).put("detail", "");
+        rights.get(1).put("enabled", false);
+        jdbc.update("update merchant set merchant_rights_config = ? where id = 88", com.alibaba.fastjson.JSON.toJSONString(rights));
+        assertThat(service.benefitTextForMerchant(88L, levels[0])).isEmpty();
+        assertThat(service.benefitTextForMerchant(88L, levels[1])).isEmpty();
+        assertThat(service.benefitTextForMerchant(88L, "普通游客")).isEmpty();
     }
 
     @Test

--
Gitblit v1.7.1