package com.tailbet.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.tailbet.model.entity.User; import com.tailbet.mapper.UserMapper; import com.tailbet.model.dto.UpdateUserDTO; import com.tailbet.service.IUserService; import com.tailbet.util.JwtUtil; import com.tailbet.util.PasswordUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; /** * 用户Service实现 */ @Slf4j @RequiredArgsConstructor @Service public class UserServiceImpl implements IUserService { private final UserMapper userMapper; private final PasswordUtil passwordUtil; private final JwtUtil jwtUtil; @Override public User getById(Long id) { return userMapper.selectById(id); } /** * 根据用户名查询用户 */ @Override public User getByUsername(String username) { return userMapper.selectOne(new LambdaQueryWrapper() .eq(User::getUsername, username)); } /** * 注册用户 */ @Override public User register(String username, String password) { // 检查用户名是否已存在 if (getByUsername(username) != null) { throw new RuntimeException("用户名已存在"); } User user = new User(); user.setUsername(username); user.setPassword(passwordUtil.encode(password)); user.setNickname(username); user.setPoints(0L); user.setStatus(1); userMapper.insert(user); // 分配运营(按最少绑定+优先在线算法) assignOps(user); return user; } /** * 用户登录 */ @Override public String login(String username, String password) { User user = getByUsername(username); if (user == null) { throw new RuntimeException("用户不存在"); } if (user.getStatus() == 0) { throw new RuntimeException("账号已被封禁"); } if (!passwordUtil.matches(password, user.getPassword())) { throw new RuntimeException("密码错误"); } return jwtUtil.generateToken(user.getId(), user.getUsername()); } /** * 更新用户 */ @Override public boolean updateUser(User user) { return userMapper.updateById(user) > 0; } /** * 更新用户信息 */ @Override public void updateUserInfo(Long userId, UpdateUserDTO dto) { User user = userMapper.selectById(userId); if (user == null) { throw new RuntimeException("用户不存在"); } if (dto.getNickname() != null && !dto.getNickname().isEmpty()) { user.setNickname(dto.getNickname()); } if (dto.getAvatarUrl() != null) { user.setAvatarUrl(dto.getAvatarUrl()); } if (dto.getPassword() != null && !dto.getPassword().isEmpty()) { user.setPassword(passwordUtil.encode(dto.getPassword())); } userMapper.updateById(user); } /** * 获取当前登录用户 */ @Override public User getCurrentUser() { return null; } /** * 分配运营(粘性绑定:在线+最少绑定) */ private void assignOps(User user) { // 查询所有运营账号 List opsList = userMapper.selectList(new LambdaQueryWrapper() .eq(User::getIsOps, 1) .eq(User::getStatus, 1)); if (opsList == null || opsList.isEmpty()) { log.warn("没有可用的运营账号,用户{}将无法分配运营", user.getUsername()); return; } // 找绑定用户最少的运营 User selectedOps = opsList.stream() .min((a, b) -> { Long countA = userMapper.selectCount(new LambdaQueryWrapper() .eq(User::getBoundOpsUserId, a.getId())); Long countB = userMapper.selectCount(new LambdaQueryWrapper() .eq(User::getBoundOpsUserId, b.getId())); return countA.compareTo(countB); }) .orElse(opsList.get(0)); user.setBoundOpsUserId(selectedOps.getId()); userMapper.updateById(user); } }