| | |
| | | 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; |
| | |
| | | private final HztClinicMapper hztClinicMapper; |
| | | private final StringRedisTemplate stringRedisTemplate; |
| | | private final ObjectMapper objectMapper; |
| | | private final AppShareService appShareService; |
| | | |
| | | /** |
| | | * 注入注册链路所需的本地库、海诊通库、验证码与缓存能力。 |
| | |
| | | HztAppUserMapper hztAppUserMapper, |
| | | HztClinicMapper hztClinicMapper, |
| | | StringRedisTemplate stringRedisTemplate, |
| | | ObjectMapper objectMapper) { |
| | | ObjectMapper objectMapper, |
| | | AppShareService appShareService) { |
| | | this.userMapper = userMapper; |
| | | this.clinicMapper = clinicMapper; |
| | | this.passwordEncoder = passwordEncoder; |
| | |
| | | this.hztClinicMapper = hztClinicMapper; |
| | | this.stringRedisTemplate = stringRedisTemplate; |
| | | this.objectMapper = objectMapper; |
| | | this.appShareService = appShareService; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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())); |
| | |
| | | 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); |
| | |
| | | /** |
| | | * 按邀请码绑定本地上级诊所用户与诊所归属。 |
| | | */ |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 归一化绑定票据。 |
| | | */ |
| | | private String normalizeBindTicket(String bindTicket) { |
| | | return trimToNull(bindTicket); |
| | | } |
| | | |
| | | /** |
| | | * 归一化经营者注册凭证。 |
| | | */ |
| | | private String normalizeRegisterTicket(String registerTicket) { |