package com.xuqm.demo.service; import com.xuqm.common.exception.BusinessException; import com.xuqm.demo.entity.DemoUserEntity; import com.xuqm.demo.repository.DemoUserRepository; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service public class DemoUserService { private final DemoUserRepository userRepository; private final PasswordEncoder passwordEncoder; public DemoUserService(DemoUserRepository userRepository, PasswordEncoder passwordEncoder) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; } public record UserProfile(String appId, String userId, String nickname, String avatar, String gender) {} @Transactional(readOnly = true) public UserProfile getProfile(String appId, String userId) { DemoUserEntity user = userRepository.findByAppIdAndUserId(appId, userId) .orElseThrow(() -> new BusinessException(404, "User not found")); return toProfile(user); } @Transactional public UserProfile updateProfile(String appId, String userId, String nickname, String avatar, String gender) { DemoUserEntity user = userRepository.findByAppIdAndUserId(appId, userId) .orElseThrow(() -> new BusinessException(404, "User not found")); if (nickname != null && !nickname.isBlank()) { user.setNickname(nickname); } if (avatar != null) { user.setAvatar(avatar.isBlank() ? null : avatar); } if (gender != null) { try { user.setGender(DemoUserEntity.Gender.valueOf(gender.toUpperCase())); } catch (IllegalArgumentException e) { throw new BusinessException(400, "Invalid gender value: " + gender); } } userRepository.save(user); return toProfile(user); } @Transactional public void resetPassword(String appId, String userId, String oldPassword, String newPassword) { DemoUserEntity user = userRepository.findByAppIdAndUserId(appId, userId) .orElseThrow(() -> new BusinessException(404, "User not found")); if (!passwordEncoder.matches(oldPassword, user.getPasswordHash())) { throw new BusinessException(401, "Old password is incorrect"); } if (newPassword == null || newPassword.length() < 6) { throw new BusinessException(400, "New password must be at least 6 characters"); } user.setPasswordHash(passwordEncoder.encode(newPassword)); userRepository.save(user); } @Transactional(readOnly = true) public List searchUsers(String appId, String keyword) { if (keyword == null || keyword.isBlank()) { throw new BusinessException(400, "Search keyword must not be blank"); } return userRepository.searchByKeyword(appId, keyword.trim()) .stream() .map(this::toProfile) .toList(); } private UserProfile toProfile(DemoUserEntity user) { return new UserProfile( user.getAppId(), user.getUserId(), user.getNickname(), user.getAvatar(), user.getGender() != null ? user.getGender().name() : DemoUserEntity.Gender.UNKNOWN.name() ); } }