From 65085442d5e6dfe2eaa0c7794a2fbc09d801a0dd Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 12 十月 2026 14:36:19 +0800
Subject: [PATCH] fix(merchant): 纳管的商家登录提示不再误报,并修掉读库键名写错

---
 talent-card-server/src/test/java/com/talentcard/server/business/admin/MerchantManagedOnboardingTests.java |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/talent-card-server/src/test/java/com/talentcard/server/business/admin/MerchantManagedOnboardingTests.java b/talent-card-server/src/test/java/com/talentcard/server/business/admin/MerchantManagedOnboardingTests.java
index 371c846..a459b8b 100644
--- a/talent-card-server/src/test/java/com/talentcard/server/business/admin/MerchantManagedOnboardingTests.java
+++ b/talent-card-server/src/test/java/com/talentcard/server/business/admin/MerchantManagedOnboardingTests.java
@@ -388,6 +388,60 @@
         assertThat(service.adopt(fixture.merchantId(), huifuId, APPLY_NO, true)).containsEntry("status", "approved");
     }
 
+    /**
+     * 登录开着、账号也在的商家**一条提示都不该有**。
+     *
+     * <p>这条钉的是一个真出现过的静默 bug:库行经 {@code DatabaseRows.normalize} 后键是 camelCase,
+     * 通道回执是 snake_case,两种 map 用同一个 {@code get()} 取,于是把列名写成 snake_case 去读库行会
+     * 取到 null(不报错),`!"1".equals("")` 恒真——登录明明开着,界面上却永远挂着「未开启商户端登录」。
+     * 只有「正向不提示」的断言能发现它,只测「没开时要提示」是测不出来的。
+     */
+    @Test
+    void noLoginNoticeAtAllWhenTheMerchantCanAlreadySignIn() {
+        String huifuId = uniqueHuifuId();
+        Fixture fixture = merchantFixture("登录开着");
+        jdbc.update("""
+                insert into merchant_operator(merchant_id, account, password_hash, display_name, role_code, status, deleted)
+                values (?, ?, 'x', '店主', 'owner', 1, 0)
+                """, fixture.merchantId(), "t01ok" + Math.abs(System.nanoTime()));
+        stubConvergedChannel(huifuId, "622200001234", "external-card-token");
+
+        assertThat(service.preview(fixture.merchantId(), huifuId).get("loginNotice")).isEqualTo("");
+    }
+
+    /**
+     * 通道没给联系人/手机号时,这些非空字段要从**我们自己的商家记录**取,不能留空、也不能顶成别的字段。
+     *
+     * <p>与上一条同源:它覆盖的正是「拿 snake_case 的键去读库行」会静默取到 null 的那几处。
+     */
+    @Test
+    void missingChannelContactFieldsFallBackToOurMerchantRecord() {
+        String huifuId = uniqueHuifuId();
+        Fixture fixture = merchantFixture("通道缺联系人");
+        Map<String, Object> detail = channelDetail(huifuId, "622200001234", "external-card-token", "Y", true);
+        // 个人主体:company_type 取我们商家档案上的经营类型;通道侧的联系人三项全部不给。
+        detail.put("cust_type", "2");
+        detail.remove("contact_name");
+        detail.remove("contact_mobile_no");
+        detail.remove("legal_mobile_no");
+        when(gateway.queryCapabilities(huifuId)).thenReturn(detail);
+        when(gateway.queryApplication(anyString(), anyString())).thenReturn(Map.of(
+                "resp_code", "00000000", "apply_status", "Y", "reg_status", "S", "bind_card_status", "S"));
+
+        service.adopt(fixture.merchantId(), huifuId, APPLY_NO, true);
+
+        // merchantFixture 的商家记录:contact_name=联系人、contact_mobile=13700000001、merchant_type=餐饮服务
+        assertThat(column(fixture, "contact_name")).isEqualTo("联系人");
+        assertThat(column(fixture, "contact_mobile")).isEqualTo("13700000001");
+        assertThat(column(fixture, "company_type")).isEqualTo("餐饮服务");
+        assertThat(column(fixture, "subject_type")).isEqualTo("individual");
+    }
+
+    private String column(Fixture fixture, String name) {
+        return jdbc.queryForObject("select " + name + " from merchant_onboarding_application where merchant_id = ?",
+                String.class, fixture.merchantId());
+    }
+
     /** 通道没给出可用结算卡时不纳管:没有结算卡,进度不会推进、闸门也不会放行。 */
     @Test
     void adoptingIsRejectedWhenTheChannelReturnsNoUsableCard() {

--
Gitblit v1.7.1