From b82daad16c59c9770f6a0492e1a89514d41e6f71 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期一, 27 四月 2026 18:58:06 +0800
Subject: [PATCH] fix:安卓推广码绑定

---
 tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java |   51 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
index 7264117..384f3e2 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
@@ -8,6 +8,7 @@
 import com.tcm.training.admin.app.integration.haizhentong.entity.HztClinic;
 import com.tcm.training.admin.app.integration.haizhentong.mapper.HztAppUserMapper;
 import com.tcm.training.admin.app.integration.haizhentong.mapper.HztClinicMapper;
+import com.tcm.training.admin.app.share.service.AppShareService;
 import com.tcm.training.admin.app.register.dto.AppRegisterOperatorCompleteRequest;
 import com.tcm.training.admin.app.register.dto.AppRegisterOperatorPrepareRequest;
 import com.tcm.training.admin.app.register.dto.AppRegisterUserRequest;
@@ -54,6 +55,7 @@
     private final HztClinicMapper hztClinicMapper;
     private final StringRedisTemplate stringRedisTemplate;
     private final ObjectMapper objectMapper;
+    private final AppShareService appShareService;
 
     /**
      * 注入注册链路所需的本地库、海诊通库、验证码与缓存能力。
@@ -66,7 +68,8 @@
                               HztAppUserMapper hztAppUserMapper,
                               HztClinicMapper hztClinicMapper,
                               StringRedisTemplate stringRedisTemplate,
-                              ObjectMapper objectMapper) {
+                              ObjectMapper objectMapper,
+                              AppShareService appShareService) {
         this.userMapper = userMapper;
         this.clinicMapper = clinicMapper;
         this.passwordEncoder = passwordEncoder;
@@ -76,6 +79,7 @@
         this.hztClinicMapper = hztClinicMapper;
         this.stringRedisTemplate = stringRedisTemplate;
         this.objectMapper = objectMapper;
+        this.appShareService = appShareService;
     }
 
     /**
@@ -109,6 +113,7 @@
         String phone = normalizePhone(request.getPhone());
         String password = normalizePassword(request.getPassword());
         String inviteCode = normalizeInviteCode(request.getInviteCode());
+        String bindTicket = normalizeBindTicket(request.getBindTicket());
 
         ensurePhoneAvailable(phone);
         appSmsCodeService.validateRegisterCode(phone, normalizeCode(request.getCode()));
@@ -123,8 +128,8 @@
         HztAppUser hztAppUser = findHztAppUserByPhone(phone);
         populateUserProfile(user, hztAppUser, phone);
 
-        // 邀请码命中时绑定上级诊所用户,并继承该诊所关系。
-        bindSuperiorClinicIfNecessary(user, inviteCode);
+        // 绑定票据优先于邀请码,避免安装后丢失或误填导致关系错误。
+        bindSuperiorClinicIfNecessary(user, inviteCode, bindTicket);
 
         userMapper.insert(user);
         return new AppRegisterResultVO(user.getId(), user.getType(), user.getClinicId(), null);
@@ -206,27 +211,26 @@
     /**
      * 按邀请码绑定本地上级诊所用户与诊所归属。
      */
-    private void bindSuperiorClinicIfNecessary(AppUser user, String inviteCode) {
-        if (inviteCode == null) {
+    private void bindSuperiorClinicIfNecessary(AppUser user, String inviteCode, String bindTicket) {
+        AppShareService.InviteBindingTarget bindingTarget = resolveInviteBindingTarget(inviteCode, bindTicket);
+        if (bindingTarget == null) {
             return;
         }
-        Clinic clinic = clinicMapper.selectOne(new LambdaQueryWrapper<Clinic>()
-                .eq(Clinic::getInviteCode, inviteCode)
-                .eq(Clinic::getDeleted, 0)
-                .last("limit 1"));
-        if (clinic == null) {
-            throw new IllegalArgumentException("邀请码无效");
+        user.setClinicId(bindingTarget.getClinicId());
+        user.setSuperiorClinicUserId(bindingTarget.getSuperiorClinicUserId());
+    }
+
+    /**
+     * 解析注册阶段应绑定的目标关系,票据优先于邀请码。
+     */
+    private AppShareService.InviteBindingTarget resolveInviteBindingTarget(String inviteCode, String bindTicket) {
+        if (bindTicket != null) {
+            return appShareService.consumeBindTicket(bindTicket);
         }
-        AppUser clinicUser = userMapper.selectOne(new LambdaQueryWrapper<AppUser>()
-                .eq(AppUser::getClinicId, clinic.getId())
-                .eq(AppUser::getType, 1)
-                .eq(AppUser::getDeleted, 0)
-                .last("limit 1"));
-        if (clinicUser == null) {
-            throw new IllegalArgumentException("邀请码暂不可用,请联系诊所管理员");
+        if (inviteCode == null) {
+            return null;
         }
-        user.setClinicId(clinicUser.getClinicId());
-        user.setSuperiorClinicUserId(clinicUser.getId());
+        return appShareService.resolveInviteBindingTarget(inviteCode);
     }
 
     /**
@@ -463,6 +467,13 @@
     }
 
     /**
+     * 归一化绑定票据。
+     */
+    private String normalizeBindTicket(String bindTicket) {
+        return trimToNull(bindTicket);
+    }
+
+    /**
      * 归一化经营者注册凭证。
      */
     private String normalizeRegisterTicket(String registerTicket) {

--
Gitblit v1.7.1