package com.rongyichuang.user.service;
|
|
import com.rongyichuang.user.entity.User;
|
import com.rongyichuang.user.repository.UserRepository;
|
import com.rongyichuang.employee.repository.EmployeeRepository;
|
import com.rongyichuang.judge.repository.JudgeRepository;
|
import com.rongyichuang.player.repository.PlayerRepository;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.util.Optional;
|
|
/**
|
* 用户服务类
|
*/
|
@Service
|
@Transactional
|
public class UserService {
|
|
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
|
@Autowired
|
private UserRepository userRepository;
|
|
@Autowired
|
private EmployeeRepository employeeRepository;
|
|
@Autowired
|
private JudgeRepository judgeRepository;
|
|
@Autowired
|
private PlayerRepository playerRepository;
|
|
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
|
/**
|
* 根据手机号查找或创建用户
|
* 如果用户存在,更新姓名和密码(如果提供了密码)
|
* 如果用户不存在,创建新用户
|
*
|
* @param phone 手机号
|
* @param name 姓名
|
* @param password 密码(可以为null,表示不更新密码)
|
* @return 用户实体
|
*/
|
public User findOrCreateUserByPhone(String phone, String name, String password) {
|
Optional<User> existingUser = userRepository.findByPhone(phone);
|
|
if (existingUser.isPresent()) {
|
// 用户存在,更新姓名和密码(如果提供了密码)
|
User user = existingUser.get();
|
user.setName(name);
|
if (password != null && !password.trim().isEmpty()) {
|
user.setPassword(passwordEncoder.encode(password));
|
}
|
return userRepository.save(user);
|
} else {
|
// 用户不存在,创建新用户
|
User newUser = new User();
|
newUser.setName(name);
|
newUser.setPhone(phone);
|
if (password != null && !password.trim().isEmpty()) {
|
newUser.setPassword(passwordEncoder.encode(password));
|
} else {
|
// 如果没有提供密码,设置一个默认密码
|
newUser.setPassword(passwordEncoder.encode("123456"));
|
}
|
return userRepository.save(newUser);
|
}
|
}
|
|
/**
|
* 根据手机号查找用户
|
*/
|
public Optional<User> findByPhone(String phone) {
|
return userRepository.findByPhone(phone);
|
}
|
|
/**
|
* 保存用户
|
*/
|
public User save(User user) {
|
return userRepository.save(user);
|
}
|
|
/**
|
* 根据ID查找用户
|
*/
|
public Optional<User> findById(Long id) {
|
return userRepository.findById(id);
|
}
|
|
/**
|
* 保存用户手机号码
|
* 核心逻辑:
|
* 1. 查询当前t_user里面是否存在相同的电话号码,如果没有,就更新到当前user里面
|
* 2. 如果存在相同的电话号码,并且对应user的openid是null,那么清空原来user的phone设置为null,
|
* 把新的电话号码更新到当前用户的phone字段,同时更新t_player、t_judge、t_employee关联的user_id到新的user_id
|
*
|
* @param currentUserId 当前用户ID
|
* @param phone 要保存的手机号码
|
* @return 更新后的用户实体
|
*/
|
@Transactional
|
public User saveUserPhone(Long currentUserId, String phone) {
|
logger.info("开始处理用户手机号码保存,用户ID: {}, 手机号: {}", currentUserId, phone);
|
|
// 获取当前用户
|
User currentUser = userRepository.findById(currentUserId)
|
.orElseThrow(() -> new RuntimeException("用户不存在,ID: " + currentUserId));
|
|
// 检查是否存在相同手机号的用户
|
Optional<User> existingPhoneUser = userRepository.findByPhone(phone);
|
|
if (existingPhoneUser.isEmpty()) {
|
// 情况1:没有其他用户使用这个手机号,直接更新当前用户
|
logger.info("手机号 {} 未被使用,直接更新到用户 {}", phone, currentUserId);
|
currentUser.setPhone(phone);
|
return userRepository.save(currentUser);
|
} else {
|
User phoneUser = existingPhoneUser.get();
|
|
// 如果是同一个用户,无需处理
|
if (phoneUser.getId().equals(currentUserId)) {
|
logger.info("手机号 {} 已属于当前用户 {},无需更新", phone, currentUserId);
|
return currentUser;
|
}
|
|
// 情况2:存在相同手机号的用户,且该用户的openid为null
|
if (phoneUser.getWxOpenid() == null || phoneUser.getWxOpenid().trim().isEmpty()) {
|
logger.info("发现手机号 {} 被用户 {} 使用,但该用户无openid,开始数据迁移", phone, phoneUser.getId());
|
|
// 迁移关联数据
|
migrateUserRelatedData(phoneUser.getId(), currentUserId);
|
|
// 清空原用户的手机号
|
phoneUser.setPhone(null);
|
userRepository.save(phoneUser);
|
logger.info("已清空原用户 {} 的手机号", phoneUser.getId());
|
|
// 更新当前用户的手机号
|
currentUser.setPhone(phone);
|
User savedUser = userRepository.save(currentUser);
|
logger.info("已将手机号 {} 更新到当前用户 {}", phone, currentUserId);
|
|
return savedUser;
|
} else {
|
// 情况3:存在相同手机号的用户,且该用户有openid,不能覆盖
|
logger.warn("手机号 {} 已被用户 {} 使用,且该用户有openid,无法更新", phone, phoneUser.getId());
|
throw new RuntimeException("手机号已被其他微信用户使用,无法更新");
|
}
|
}
|
}
|
|
/**
|
* 迁移用户关联数据
|
* 将原用户的员工、评委、学员信息迁移到新用户
|
*
|
* @param fromUserId 原用户ID
|
* @param toUserId 目标用户ID
|
*/
|
private void migrateUserRelatedData(Long fromUserId, Long toUserId) {
|
logger.info("开始迁移用户关联数据,从用户 {} 到用户 {}", fromUserId, toUserId);
|
|
// 迁移员工信息
|
employeeRepository.findByUserId(fromUserId).ifPresent(employee -> {
|
logger.info("迁移员工信息,员工ID: {}, 姓名: {}", employee.getId(), employee.getName());
|
employee.setUserId(toUserId);
|
employeeRepository.save(employee);
|
});
|
|
// 迁移评委信息
|
judgeRepository.findByUserId(fromUserId).ifPresent(judge -> {
|
logger.info("迁移评委信息,评委ID: {}, 姓名: {}", judge.getId(), judge.getName());
|
judge.setUserId(toUserId);
|
judgeRepository.save(judge);
|
});
|
|
// 迁移学员信息
|
playerRepository.findByUserId(fromUserId).ifPresent(player -> {
|
logger.info("迁移学员信息,学员ID: {}, 姓名: {}", player.getId(), player.getName());
|
player.setUserId(toUserId);
|
playerRepository.save(player);
|
});
|
|
logger.info("用户关联数据迁移完成");
|
}
|
}
|