| | |
| | | import com.rongyichuang.auth.dto.LoginResponse.JudgeInfo; |
| | | import com.rongyichuang.auth.dto.LoginResponse.PlayerInfo; |
| | | import com.rongyichuang.common.util.UserContextUtil; |
| | | import com.rongyichuang.auth.util.JwtUtil; |
| | | import com.rongyichuang.employee.entity.Employee; |
| | | import com.rongyichuang.employee.service.EmployeeService; |
| | | import com.rongyichuang.judge.entity.Judge; |
| | | import com.rongyichuang.judge.service.JudgeService; |
| | | import com.rongyichuang.player.entity.Player; |
| | | import com.rongyichuang.player.service.PlayerService; |
| | | import com.rongyichuang.player.repository.ActivityPlayerRepository; |
| | | import com.rongyichuang.common.repository.MediaRepository; |
| | | import com.rongyichuang.common.entity.Media; |
| | | import com.rongyichuang.common.enums.MediaTargetType; |
| | | import com.rongyichuang.media.service.MediaV2Service; |
| | | import com.rongyichuang.media.dto.MediaSaveInput; |
| | | import com.rongyichuang.media.dto.MediaSaveResponse; |
| | | import com.rongyichuang.user.dto.response.UserProfile; |
| | | import com.rongyichuang.user.dto.response.UserStats; |
| | | import com.rongyichuang.user.dto.response.UserRegistration; |
| | | import com.rongyichuang.user.dto.response.UserProject; |
| | | import com.rongyichuang.user.dto.request.UserInput; |
| | | import com.rongyichuang.user.dto.response.UserProfileInfo; |
| | | import com.rongyichuang.user.entity.User; |
| | | import com.rongyichuang.user.repository.UserRepository; |
| | | import com.rongyichuang.player.dto.response.SubmissionMediaResponse; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.graphql.data.method.annotation.Argument; |
| | | import org.springframework.graphql.data.method.annotation.QueryMapping; |
| | | import org.springframework.graphql.data.method.annotation.MutationMapping; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import jakarta.persistence.EntityManager; |
| | | import jakarta.persistence.PersistenceContext; |
| | | import jakarta.persistence.Query; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Optional; |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * 用户GraphQL解析器 |
| | |
| | | private PlayerService playerService; |
| | | |
| | | @Autowired |
| | | private ActivityPlayerRepository activityPlayerRepository; |
| | | |
| | | @Autowired |
| | | private MediaRepository mediaRepository; |
| | | |
| | | @Autowired |
| | | private UserRepository userRepository; |
| | | |
| | | @PersistenceContext |
| | | private EntityManager entityManager; |
| | | |
| | | @Autowired |
| | | private UserContextUtil userContextUtil; |
| | | |
| | | @Autowired |
| | | private JwtUtil jwtUtil; |
| | | |
| | | @Autowired |
| | | private MediaV2Service mediaV2Service; |
| | | |
| | | @Value("${app.media-url}") |
| | | private String mediaBaseUrl; |
| | | |
| | | /** |
| | | * 获取当前用户档案 |
| | |
| | | try { |
| | | Long userId = userContextUtil.getCurrentUserId(); |
| | | logger.debug("进入userProfile,解析到用户ID: {}", userId); |
| | | |
| | | // 如果是匿名用户,返回基本的用户档案 |
| | | if (userId == null) { |
| | | throw new RuntimeException("用户未登录"); |
| | | logger.debug("匿名用户访问userProfile,返回基本档案"); |
| | | UserProfile profile = new UserProfile(); |
| | | profile.setId("0"); // 匿名用户ID设为0 |
| | | profile.setName("匿名用户"); |
| | | profile.setRoles(new ArrayList<>()); |
| | | profile.setUserType("user"); // 匿名用户类型为普通用户 |
| | | profile.setCreatedAt(java.time.LocalDateTime.now().toString()); |
| | | return profile; |
| | | } |
| | | |
| | | UserProfile profile = new UserProfile(); |
| | | profile.setId(userId.toString()); |
| | | |
| | | // 获取用户基本信息 |
| | | Optional<User> userOpt = userRepository.findById(userId); |
| | | User user = null; |
| | | if (userOpt.isPresent()) { |
| | | user = userOpt.get(); |
| | | // 设置基本信息(姓名和电话号码) |
| | | profile.setName(user.getName()); |
| | | profile.setPhone(user.getPhone()); |
| | | // 设置性别 |
| | | if (user.getGender() != null) { |
| | | profile.setGender(user.getGender() == 1 ? "MALE" : "FEMALE"); |
| | | } |
| | | // 设置生日 |
| | | if (user.getBirthday() != null) { |
| | | profile.setBirthday(user.getBirthday().toString()); |
| | | } |
| | | } |
| | | |
| | | List<String> roles = new ArrayList<>(); |
| | | |
| | |
| | | Employee employee = employeeService.findByUserId(userId); |
| | | logger.debug("员工查询结果: {}", employee != null ? ("id=" + employee.getId() + ", name=" + employee.getName()) : "无"); |
| | | if (employee != null) { |
| | | profile.setName(employee.getName()); |
| | | profile.setPhone(employee.getPhone()); |
| | | // 如果员工信息存在,则覆盖基本信息 |
| | | if (employee.getName() != null) { |
| | | profile.setName(employee.getName()); |
| | | } |
| | | if (employee.getPhone() != null) { |
| | | profile.setPhone(employee.getPhone()); |
| | | } |
| | | roles.add("EMPLOYEE"); |
| | | |
| | | EmployeeInfo employeeInfo = new EmployeeInfo( |
| | |
| | | Judge judge = judgeService.findByUserId(userId); |
| | | logger.debug("评委查询结果: {}", judge != null ? ("id=" + judge.getId() + ", name=" + judge.getName()) : "无"); |
| | | if (judge != null) { |
| | | if (profile.getName() == null) { |
| | | // 如果评委信息存在且基本信息为空,则设置评委信息 |
| | | if (profile.getName() == null && judge.getName() != null) { |
| | | profile.setName(judge.getName()); |
| | | } |
| | | if (profile.getPhone() == null && judge.getPhone() != null) { |
| | | profile.setPhone(judge.getPhone()); |
| | | } |
| | | roles.add("JUDGE"); |
| | |
| | | Player player = playerService.findByUserId(userId); |
| | | logger.debug("学员查询结果: {}", player != null ? ("id=" + player.getId() + ", name=" + player.getName()) : "无"); |
| | | if (player != null) { |
| | | if (profile.getName() == null) { |
| | | // 如果学员信息存在且基本信息为空,则设置学员信息 |
| | | if (profile.getName() == null && player.getName() != null) { |
| | | profile.setName(player.getName()); |
| | | profile.setPhone(player.getPhone()); |
| | | } |
| | | // 不再从Player获取phone信息,phone统一从User实体获取 |
| | | // if (profile.getPhone() == null && player.getPhone() != null) { |
| | | // profile.setPhone(player.getPhone()); |
| | | // } |
| | | roles.add("PLAYER"); |
| | | |
| | | PlayerInfo playerInfo = new PlayerInfo( |
| | |
| | | } |
| | | |
| | | profile.setRoles(roles); |
| | | logger.debug("userProfile构建完成,roles={}, name={}, phone={}", roles, profile.getName(), profile.getPhone()); |
| | | |
| | | // 确定主要角色类型(优先级:employee > judge > player) |
| | | String userType; |
| | | if (employee != null) { |
| | | userType = "employee"; |
| | | } else if (judge != null) { |
| | | userType = "judge"; |
| | | } else if (player != null) { |
| | | userType = "player"; |
| | | } else { |
| | | userType = "user"; // 普通用户 |
| | | } |
| | | profile.setUserType(userType); |
| | | logger.debug("设置用户类型: {}", userType); |
| | | |
| | | // 获取用户头像 |
| | | try { |
| | | List<Media> avatarMediaList = mediaRepository.findByTargetTypeAndTargetIdAndState( |
| | | MediaTargetType.USER_AVATAR.getValue(), |
| | | userId, |
| | | 1 |
| | | ); |
| | | if (!avatarMediaList.isEmpty()) { |
| | | Media avatarMedia = avatarMediaList.get(0); |
| | | String fullAvatarUrl = buildFullMediaUrl(avatarMedia.getPath()); |
| | | profile.setAvatar(fullAvatarUrl); |
| | | logger.debug("找到用户头像: {} -> {}", avatarMedia.getPath(), fullAvatarUrl); |
| | | } else { |
| | | logger.debug("用户{}没有找到头像", userId); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.warn("获取用户头像失败: {}", e.getMessage()); |
| | | } |
| | | |
| | | logger.debug("userProfile构建完成,roles={}, name={}, phone={}, avatar={}", |
| | | roles, profile.getName(), profile.getPhone(), profile.getAvatar()); |
| | | profile.setCreatedAt(java.time.LocalDateTime.now().toString()); |
| | | |
| | | return profile; |
| | |
| | | @QueryMapping |
| | | public UserStats userStats() { |
| | | try { |
| | | Long userId = UserContextUtil.getCurrentUserId(); |
| | | Long userId = userContextUtil.getCurrentUserId(); |
| | | if (userId == null) { |
| | | return null; |
| | | } |
| | |
| | | @QueryMapping |
| | | public List<UserRegistration> myRegistrations(@Argument Integer limit) { |
| | | try { |
| | | Long userId = UserContextUtil.getCurrentUserId(); |
| | | Long userId = userContextUtil.getCurrentUserId(); |
| | | if (userId == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 这里应该实现真正的报名记录查询逻辑 |
| | | // 暂时返回空列表 |
| | | return new ArrayList<>(); |
| | | // 构建SQL查询,获取用户的报名记录 |
| | | StringBuilder sql = new StringBuilder(); |
| | | sql.append("SELECT ap.id, a.id as activity_id, a.name as activity_name, "); |
| | | sql.append("ap.project_name, ap.state, ap.create_time, "); |
| | | sql.append("m.path as cover_image_path "); |
| | | sql.append("FROM t_activity_player ap "); |
| | | sql.append("INNER JOIN t_player p ON ap.player_id = p.id "); |
| | | sql.append("INNER JOIN t_activity a ON ap.activity_id = a.id "); |
| | | sql.append("LEFT JOIN t_media m ON a.cover_image_id = m.id "); |
| | | sql.append("WHERE p.user_id = :userId "); |
| | | sql.append("ORDER BY ap.create_time DESC"); |
| | | |
| | | if (limit != null && limit > 0) { |
| | | sql.append(" LIMIT :limit"); |
| | | } |
| | | |
| | | Query query = entityManager.createNativeQuery(sql.toString()); |
| | | query.setParameter("userId", userId); |
| | | if (limit != null && limit > 0) { |
| | | query.setParameter("limit", limit); |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | List<Object[]> results = query.getResultList(); |
| | | |
| | | List<UserRegistration> registrations = new ArrayList<>(); |
| | | for (Object[] row : results) { |
| | | UserRegistration registration = new UserRegistration(); |
| | | registration.setId(String.valueOf(row[0])); |
| | | |
| | | // 创建ActivityInfo |
| | | UserRegistration.ActivityInfo activityInfo = new UserRegistration.ActivityInfo(); |
| | | activityInfo.setId(String.valueOf(row[1])); |
| | | activityInfo.setTitle((String) row[2]); |
| | | |
| | | // 设置封面图片 |
| | | if (row[6] != null) { |
| | | UserRegistration.MediaInfo mediaInfo = new UserRegistration.MediaInfo(); |
| | | mediaInfo.setPath((String) row[6]); |
| | | mediaInfo.setFullUrl(buildFullMediaUrl((String) row[6])); |
| | | activityInfo.setCoverImage(mediaInfo); |
| | | } |
| | | |
| | | registration.setActivity(activityInfo); |
| | | |
| | | // 设置状态 |
| | | Integer state = (Integer) row[4]; |
| | | String status = "pending"; |
| | | if (state != null) { |
| | | switch (state) { |
| | | case 0: status = "pending"; break; |
| | | case 1: status = "approved"; break; |
| | | case 2: status = "rejected"; break; |
| | | default: status = "unknown"; break; |
| | | } |
| | | } |
| | | registration.setStatus(status); |
| | | |
| | | // 设置报名时间 |
| | | if (row[5] != null) { |
| | | registration.setRegistrationTime(row[5].toString()); |
| | | } |
| | | |
| | | registrations.add(registration); |
| | | } |
| | | |
| | | return registrations; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | logger.error("获取用户报名记录失败", e); |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取我的项目列表 |
| | | */ |
| | | @QueryMapping |
| | | public List<UserProject> myProjects() { |
| | | try { |
| | | Long userId = userContextUtil.getCurrentUserId(); |
| | | logger.debug("获取用户项目列表,userId: {}", userId); |
| | | if (userId == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 查询用户的所有项目(state = 0, 1, 2) |
| | | // 使用 t_activity_player join t_player join t_user 的方式通过用户ID查询 |
| | | String sql = """ |
| | | SELECT ap.id, ap.project_name, a.name as activity_name, ap.state, ap.create_time |
| | | FROM t_activity_player ap |
| | | JOIN t_player p ON ap.player_id = p.id |
| | | JOIN t_activity a ON a.id = ap.activity_id |
| | | WHERE p.user_id = ? AND ap.state IN (0, 1, 2) |
| | | ORDER BY ap.create_time DESC |
| | | """; |
| | | |
| | | Query query = entityManager.createNativeQuery(sql); |
| | | query.setParameter(1, userId); |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | List<Object[]> results = query.getResultList(); |
| | | |
| | | List<UserProject> projects = new ArrayList<>(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | for (Object[] row : results) { |
| | | String id = row[0].toString(); |
| | | String projectName = row[1] != null ? row[1].toString() : ""; |
| | | String activityName = row[2] != null ? row[2].toString() : ""; |
| | | String status = row[3] != null ? row[3].toString() : "0"; |
| | | String createTime = row[4] != null ? row[4].toString() : ""; |
| | | |
| | | UserProject project = new UserProject(id, projectName, activityName, status, createTime); |
| | | |
| | | // 查询项目的提交文件 |
| | | List<SubmissionMediaResponse> submissionFiles = getSubmissionFiles(Long.parseLong(id)); |
| | | project.setSubmissionFiles(submissionFiles); |
| | | |
| | | projects.add(project); |
| | | } |
| | | |
| | | logger.debug("查询到 {} 个项目", projects.size()); |
| | | return projects; |
| | | } catch (Exception e) { |
| | | logger.error("获取用户项目列表失败", e); |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取项目的提交文件 |
| | | * @param activityPlayerId 活动参与者ID |
| | | * @return 提交文件列表 |
| | | */ |
| | | private List<SubmissionMediaResponse> getSubmissionFiles(Long activityPlayerId) { |
| | | try { |
| | | // 查询提交的媒体文件 (target_type = 5 表示活动参与者提交的文件,state = 1 表示有效状态) |
| | | List<Media> medias = mediaRepository.findByTargetTypeAndTargetIdAndState(5, activityPlayerId, 1); |
| | | |
| | | List<SubmissionMediaResponse> submissionFiles = new ArrayList<>(); |
| | | for (Media media : medias) { |
| | | SubmissionMediaResponse response = new SubmissionMediaResponse(); |
| | | response.setId(media.getId()); |
| | | response.setName(media.getName()); |
| | | response.setPath(media.getPath()); |
| | | response.setUrl(buildFullMediaUrl(media.getPath())); |
| | | response.setFullUrl(buildFullMediaUrl(media.getPath())); |
| | | response.setFullThumbUrl(buildFullMediaUrl(media.getThumbPath())); |
| | | response.setFileExt(media.getFileExt()); |
| | | response.setFileSize(media.getFileSize() != null ? media.getFileSize().longValue() : null); |
| | | response.setMediaType(media.getMediaType()); |
| | | response.setThumbUrl(buildFullMediaUrl(media.getThumbPath())); |
| | | submissionFiles.add(response); |
| | | } |
| | | |
| | | return submissionFiles; |
| | | } catch (Exception e) { |
| | | logger.error("获取项目提交文件失败,activityPlayerId: {}", activityPlayerId, e); |
| | | return new ArrayList<>(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构建完整的媒体URL |
| | | * @param path 媒体路径 |
| | | * @return 完整的URL |
| | | */ |
| | | private String buildFullMediaUrl(String path) { |
| | | if (!StringUtils.hasText(path)) { |
| | | return null; |
| | | } |
| | | |
| | | // 如果路径已经是完整URL,直接返回 |
| | | if (path.startsWith("http://") || path.startsWith("https://")) { |
| | | return path; |
| | | } |
| | | |
| | | // 构建完整URL |
| | | if (StringUtils.hasText(mediaBaseUrl)) { |
| | | // 确保baseUrl以/结尾,path不以/开头 |
| | | String baseUrl = mediaBaseUrl.endsWith("/") ? mediaBaseUrl : mediaBaseUrl + "/"; |
| | | String relativePath = path.startsWith("/") ? path.substring(1) : path; |
| | | return baseUrl + relativePath; |
| | | } |
| | | |
| | | // 如果没有配置baseUrl,返回原路径 |
| | | return path; |
| | | } |
| | | |
| | | /** |
| | | * 保存用户信息 |
| | | */ |
| | | @MutationMapping |
| | | public UserProfileInfo saveUserInfo(@Argument UserInput input) { |
| | | try { |
| | | Long userId = userContextUtil.getCurrentUserIdIncludingAnonymous(); |
| | | logger.debug("进入saveUserInfo,解析到用户ID(包括匿名用户): {}", userId); |
| | | if (userId == null) { |
| | | throw new RuntimeException("用户未登录"); |
| | | } |
| | | |
| | | User user; |
| | | boolean isNewUser = false; |
| | | |
| | | // 检查手机号是否存在 |
| | | if (StringUtils.hasText(input.getPhone())) { |
| | | Optional<User> existingUserByPhone = userRepository.findByPhone(input.getPhone()); |
| | | if (existingUserByPhone.isPresent()) { |
| | | // 手机号已存在,更新现有用户 |
| | | user = existingUserByPhone.get(); |
| | | logger.debug("手机号{}已存在,更新现有用户,用户ID: {}", input.getPhone(), user.getId()); |
| | | |
| | | // 如果当前用户ID与手机号对应的用户ID不同,需要处理匿名用户转正的情况 |
| | | if (!user.getId().equals(userId)) { |
| | | logger.debug("匿名用户{}转正为正式用户{}", userId, user.getId()); |
| | | |
| | | // 检查匿名用户是否有需要合并的信息 |
| | | if (userId < 0) { |
| | | // 这是匿名用户转正,检查是否有临时信息需要合并 |
| | | Optional<User> anonymousUserOpt = userRepository.findById(userId); |
| | | if (anonymousUserOpt.isPresent()) { |
| | | User anonymousUser = anonymousUserOpt.get(); |
| | | logger.debug("发现匿名用户记录,准备合并信息"); |
| | | |
| | | // 合并匿名用户的信息到正式用户(如果正式用户没有这些信息) |
| | | if (!StringUtils.hasText(user.getName()) && StringUtils.hasText(anonymousUser.getName())) { |
| | | user.setName(anonymousUser.getName()); |
| | | logger.debug("合并匿名用户的姓名: {}", anonymousUser.getName()); |
| | | } |
| | | |
| | | if (user.getGender() == null && anonymousUser.getGender() != null) { |
| | | user.setGender(anonymousUser.getGender()); |
| | | logger.debug("合并匿名用户的性别: {}", anonymousUser.getGender()); |
| | | } |
| | | |
| | | if (user.getBirthday() == null && anonymousUser.getBirthday() != null) { |
| | | user.setBirthday(anonymousUser.getBirthday()); |
| | | logger.debug("合并匿名用户的生日: {}", anonymousUser.getBirthday()); |
| | | } |
| | | |
| | | // 删除匿名用户记录(可选,避免数据冗余) |
| | | try { |
| | | userRepository.delete(anonymousUser); |
| | | logger.debug("删除匿名用户记录: {}", userId); |
| | | } catch (Exception e) { |
| | | logger.warn("删除匿名用户记录失败: {}", e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | userId = user.getId(); // 使用正式用户ID |
| | | } |
| | | } else { |
| | | // 手机号不存在,检查当前用户ID是否存在 |
| | | Optional<User> userOpt = userRepository.findById(userId); |
| | | if (userOpt.isPresent()) { |
| | | // 用户ID存在,更新信息 |
| | | user = userOpt.get(); |
| | | logger.debug("更新现有用户信息,用户ID: {}", userId); |
| | | } else { |
| | | // 用户ID不存在,创建新用户 |
| | | user = new User(); |
| | | user.setId(userId); |
| | | isNewUser = true; |
| | | logger.debug("创建新用户,用户ID: {}", userId); |
| | | } |
| | | } |
| | | } else { |
| | | // 没有提供手机号,直接根据用户ID查找或创建 |
| | | Optional<User> userOpt = userRepository.findById(userId); |
| | | if (userOpt.isPresent()) { |
| | | user = userOpt.get(); |
| | | logger.debug("更新现有用户信息,用户ID: {}", userId); |
| | | } else { |
| | | user = new User(); |
| | | user.setId(userId); |
| | | isNewUser = true; |
| | | logger.debug("创建新用户,用户ID: {}", userId); |
| | | } |
| | | } |
| | | |
| | | // 更新用户基本信息(不包含头像) |
| | | if (StringUtils.hasText(input.getName())) { |
| | | user.setName(input.getName()); |
| | | } |
| | | if (StringUtils.hasText(input.getPhone())) { |
| | | user.setPhone(input.getPhone()); |
| | | } |
| | | |
| | | // 处理性别转换:MALE -> 1, FEMALE -> 0 |
| | | if ("MALE".equals(input.getGender())) { |
| | | user.setGender(1); |
| | | } else if ("FEMALE".equals(input.getGender())) { |
| | | user.setGender(0); |
| | | } |
| | | |
| | | // 处理生日转换 |
| | | if (StringUtils.hasText(input.getBirthday())) { |
| | | try { |
| | | LocalDate birthday = LocalDate.parse(input.getBirthday()); |
| | | user.setBirthday(birthday); |
| | | } catch (Exception e) { |
| | | logger.warn("生日格式解析失败: {}", input.getBirthday(), e); |
| | | } |
| | | } |
| | | |
| | | // 处理wxopenid更新:从JWT token中获取当前用户的wxopenid |
| | | try { |
| | | String token = userContextUtil.getTokenFromRequest(); |
| | | if (token != null && jwtUtil.validateToken(token)) { |
| | | Long currentUserId = jwtUtil.getUserIdFromToken(token); |
| | | String wxopenidFromToken = jwtUtil.getWxOpenidFromToken(token); |
| | | |
| | | // 如果token中包含wxopenid,则更新用户的wxopenid |
| | | if (StringUtils.hasText(wxopenidFromToken)) { |
| | | logger.debug("从token中获取到wxopenid: {}", wxopenidFromToken); |
| | | |
| | | // 检查这个openid是否已经被其他用户使用 |
| | | Optional<User> existingUserWithOpenid = userRepository.findByWxOpenid(wxopenidFromToken); |
| | | if (existingUserWithOpenid.isEmpty() || existingUserWithOpenid.get().getId().equals(user.getId())) { |
| | | user.setWxOpenid(wxopenidFromToken); |
| | | logger.debug("设置用户wxopenid: {}", wxopenidFromToken); |
| | | } else { |
| | | logger.warn("wxopenid {} 已被其他用户使用,用户ID: {}", wxopenidFromToken, existingUserWithOpenid.get().getId()); |
| | | } |
| | | } else { |
| | | logger.debug("token中未包含wxopenid信息"); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | logger.warn("处理wxopenid更新时发生异常: {}", e.getMessage(), e); |
| | | } |
| | | |
| | | // 保存用户基本信息 |
| | | user = userRepository.save(user); |
| | | logger.debug("用户信息保存成功,用户ID: {}, 是否新用户: {}", user.getId(), isNewUser); |
| | | |
| | | // 处理头像保存 |
| | | if (StringUtils.hasText(input.getAvatar())) { |
| | | try { |
| | | logger.debug("开始保存用户头像,路径: {}", input.getAvatar()); |
| | | |
| | | // 构建MediaSaveInput |
| | | MediaSaveInput mediaSaveInput = new MediaSaveInput(); |
| | | mediaSaveInput.setTargetType("player"); // 使用"player"作为目标类型 |
| | | mediaSaveInput.setTargetId(user.getId()); |
| | | mediaSaveInput.setPath(input.getAvatar()); |
| | | mediaSaveInput.setMediaType(1); // 1表示图片 |
| | | mediaSaveInput.setFileSize(0L); // 设置默认文件大小为0,避免数据库约束错误 |
| | | |
| | | // 从路径中提取文件名和扩展名 |
| | | String fileName = input.getAvatar(); |
| | | if (fileName.contains("/")) { |
| | | fileName = fileName.substring(fileName.lastIndexOf("/") + 1); |
| | | } |
| | | mediaSaveInput.setFileName(fileName); |
| | | |
| | | if (fileName.contains(".")) { |
| | | String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); |
| | | mediaSaveInput.setFileExt(fileExt); |
| | | } |
| | | |
| | | // 保存头像媒体记录 |
| | | MediaSaveResponse saveResponse = mediaV2Service.saveMedia(mediaSaveInput); |
| | | if (saveResponse.getSuccess()) { |
| | | logger.debug("头像保存成功,媒体ID: {}", saveResponse.getMediaId()); |
| | | } else { |
| | | logger.warn("头像保存失败: {}", saveResponse.getMessage()); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("保存头像时发生错误", e); |
| | | // 头像保存失败不影响用户信息保存 |
| | | } |
| | | } |
| | | |
| | | // 构建返回结果 |
| | | UserProfileInfo result = new UserProfileInfo(); |
| | | result.setId(user.getId().toString()); |
| | | result.setName(user.getName()); |
| | | result.setPhone(user.getPhone()); |
| | | // 正确处理性别转换:1 -> MALE, 0 -> FEMALE, null -> null |
| | | if (user.getGender() != null) { |
| | | result.setGender(user.getGender() == 1 ? "MALE" : "FEMALE"); |
| | | } else { |
| | | result.setGender(null); |
| | | } |
| | | result.setBirthday(user.getBirthday() != null ? user.getBirthday().toString() : null); |
| | | result.setWxOpenId(user.getWxOpenid()); |
| | | result.setUnionId(user.getWxUnionid()); |
| | | |
| | | // 查找并设置头像URL(从t_media表获取) |
| | | try { |
| | | List<Media> avatarMedias = mediaRepository.findByTargetTypeAndTargetIdAndState( |
| | | MediaTargetType.USER_AVATAR.getValue(), |
| | | user.getId(), |
| | | 1 |
| | | ); |
| | | if (!avatarMedias.isEmpty()) { |
| | | Media avatarMedia = avatarMedias.get(0); |
| | | result.setAvatar(buildFullMediaUrl(avatarMedia.getPath())); |
| | | logger.debug("设置头像URL: {}", result.getAvatar()); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.warn("获取头像失败: {}", e.getMessage(), e); |
| | | } |
| | | |
| | | return result; |
| | | } catch (Exception e) { |
| | | logger.error("保存用户信息失败", e); |
| | | throw new RuntimeException("保存用户信息失败: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |