package com.rongyichuang.player.service; import com.rongyichuang.player.dto.ActivityRegistrationInput; import com.rongyichuang.player.dto.ActivityRegistrationResponse; import com.rongyichuang.player.dto.MediaFileInput; import com.rongyichuang.player.dto.response.PlayerRegistrationResponse; import com.rongyichuang.player.entity.ActivityPlayer; import com.rongyichuang.player.entity.Player; import com.rongyichuang.player.repository.ActivityPlayerRepository; import com.rongyichuang.player.repository.PlayerRepository; import com.rongyichuang.activity.repository.ActivityRepository; import com.rongyichuang.activity.entity.Activity; import com.rongyichuang.common.entity.Media; import com.rongyichuang.common.repository.MediaRepository; import com.rongyichuang.common.enums.MediaTargetType; import com.rongyichuang.common.util.UserContextUtil; import com.rongyichuang.user.entity.User; import com.rongyichuang.user.service.UserService; import com.rongyichuang.media.service.MediaV2Service; import com.rongyichuang.media.dto.MediaSaveInput; import com.rongyichuang.message.service.MessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; /** * 活动选手服务类 */ @Service @Transactional public class ActivityPlayerService { private static final Logger log = LoggerFactory.getLogger(ActivityPlayerService.class); @Autowired private ActivityPlayerRepository activityPlayerRepository; @Autowired private PlayerRepository playerRepository; @Autowired private ActivityRepository activityRepository; @Autowired private MediaRepository mediaRepository; @Autowired private UserContextUtil userContextUtil; @Autowired private UserService userService; @Autowired private MediaV2Service mediaV2Service; @Autowired private MessageService messageService; /** * 提交活动报名 * @param input 报名输入信息 * @return 报名结果 */ public ActivityRegistrationResponse submitActivityRegistration(ActivityRegistrationInput input) { try { log.info("开始处理活动报名,活动ID: {}, 选手姓名: {}", input.getActivityId(), input.getPlayerInfo().getName()); // 1. 验证输入参数 if (input.getActivityId() == null) { log.warn("活动ID为空"); return ActivityRegistrationResponse.error("活动ID不能为空"); } if (input.getPlayerInfo() == null || input.getPlayerInfo().getName() == null || input.getPlayerInfo().getName().trim().isEmpty()) { log.warn("选手姓名为空"); return ActivityRegistrationResponse.error("选手姓名不能为空"); } if (input.getPlayerInfo().getPhone() == null || input.getPlayerInfo().getPhone().trim().isEmpty()) { log.warn("联系电话为空"); return ActivityRegistrationResponse.error("联系电话不能为空"); } log.info("输入参数验证通过"); // 2. 查找或创建选手记录 log.info("开始查找或创建选手记录,手机号: {}", input.getPlayerInfo().getPhone()); Player player = findOrCreatePlayer(input); if (player == null) { log.error("创建选手记录失败"); return ActivityRegistrationResponse.error("创建选手记录失败"); } log.info("选手记录处理成功,选手ID: {}", player.getId()); // 3. 检查是否已经报名 log.info("检查是否已经报名,活动ID: {}, 选手ID: {}", input.getActivityId(), player.getId()); Optional existingRegistration = activityPlayerRepository .findByActivityIdAndPlayerId(input.getActivityId(), player.getId()); if (existingRegistration.isPresent()) { log.warn("选手已经报名过此活动"); return ActivityRegistrationResponse.error("您已经报名过此活动"); } log.info("未发现重复报名"); // 4. 查找第一阶段,如果没有则使用活动本身 log.info("查找活动的第一阶段,活动ID: {}", input.getActivityId()); Activity firstStage = activityRepository.findFirstStageByActivityId(input.getActivityId()); Long stageId; if (firstStage != null) { stageId = firstStage.getId(); log.info("找到第一阶段,阶段ID: {}, 阶段名称: {}", firstStage.getId(), firstStage.getName()); } else { // 如果没有找到第一阶段,使用活动本身作为阶段 stageId = input.getActivityId(); log.info("未找到第一阶段,使用活动本身作为阶段,活动ID: {}", input.getActivityId()); } // 5. 创建报名记录 log.info("开始创建报名记录"); ActivityPlayer activityPlayer = new ActivityPlayer(); activityPlayer.setActivityId(input.getActivityId()); activityPlayer.setStageId(stageId); // 绑定到第一阶段或活动本身 activityPlayer.setPlayerId(player.getId()); activityPlayer.setRegionId(input.getRegionId()); activityPlayer.setProjectName(input.getProjectName()); // 设置项目名称 activityPlayer.setDescription(input.getDescription()); // BaseEntity会自动设置createTime和updateTime log.info("ActivityPlayer对象创建完成,准备保存到数据库"); ActivityPlayer savedActivityPlayer = activityPlayerRepository.save(activityPlayer); log.info("报名记录创建成功,ID: {}", savedActivityPlayer.getId()); // 6. 保存其他媒体文件(兼容旧版本) if (input.getMediaFiles() != null && !input.getMediaFiles().isEmpty()) { saveMediaFiles(savedActivityPlayer.getId(), input.getMediaFiles()); } // 7. 保存头像媒体记录 if (input.getPlayerInfo().getAvatarMediaId() != null && !input.getPlayerInfo().getAvatarMediaId().trim().isEmpty()) { savePlayerAvatarMedia(player.getId(), input.getPlayerInfo().getAvatarMediaId()); } // 8. 保存附件媒体记录 if (input.getAttachmentMediaIds() != null && !input.getAttachmentMediaIds().isEmpty()) { log.info("开始保存附件媒体记录,报名ID: {}, 附件数量: {}", savedActivityPlayer.getId(), input.getAttachmentMediaIds().size()); saveAttachmentMediaRecords(savedActivityPlayer.getId(), input.getAttachmentMediaIds()); } return ActivityRegistrationResponse.success("报名成功", savedActivityPlayer.getId(), player.getId(), player.getUserId()); } catch (Exception e) { log.error("处理活动报名时发生错误", e); return ActivityRegistrationResponse.error("报名失败:" + e.getMessage()); } } /** * 查找或创建选手记录 */ private Player findOrCreatePlayer(ActivityRegistrationInput input) { try { // 先根据手机号查找现有选手 String phone = input.getPlayerInfo().getPhone(); Optional existingPlayerOpt = playerRepository.findByPhone(phone); if (existingPlayerOpt.isPresent()) { Player existingPlayer = existingPlayerOpt.get(); // 更新选手信息 existingPlayer.setName(input.getPlayerInfo().getName()); if (input.getPlayerInfo().getGender() != null) { existingPlayer.setGender(input.getPlayerInfo().getGender()); } if (input.getPlayerInfo().getEducation() != null) { existingPlayer.setEducation(input.getPlayerInfo().getEducation()); } if (input.getPlayerInfo().getIntroduction() != null) { existingPlayer.setIntroduction(input.getPlayerInfo().getIntroduction()); } if (input.getPlayerInfo().getDescription() != null) { existingPlayer.setDescription(input.getPlayerInfo().getDescription()); } // 更新关联的用户信息(如果存在) updateUserInfo(existingPlayer, input); // BaseEntity会自动设置updateTime return playerRepository.save(existingPlayer); } // 创建新选手 Player newPlayer = new Player(); newPlayer.setName(input.getPlayerInfo().getName()); newPlayer.setPhone(input.getPlayerInfo().getPhone()); newPlayer.setGender(input.getPlayerInfo().getGender()); newPlayer.setEducation(input.getPlayerInfo().getEducation()); newPlayer.setIntroduction(input.getPlayerInfo().getIntroduction()); newPlayer.setDescription(input.getPlayerInfo().getDescription()); newPlayer.setRoleId(1L); // 默认角色ID为1(学员角色) newPlayer.setState(1); // 1表示有效状态 // 创建或关联用户记录 User user = createOrUpdateUser(input); newPlayer.setUserId(user.getId()); // BaseEntity会自动设置createTime和updateTime Player savedPlayer = playerRepository.save(newPlayer); log.info("新选手创建成功,ID: {}, 姓名: {}", savedPlayer.getId(), savedPlayer.getName()); return savedPlayer; } catch (Exception e) { log.error("查找或创建选手记录时发生错误", e); return null; } } /** * 创建或更新用户记录 */ private User createOrUpdateUser(ActivityRegistrationInput input) { try { // 使用UserService的findOrCreateUserByPhone方法 User user = userService.findOrCreateUserByPhone( input.getPlayerInfo().getPhone(), input.getPlayerInfo().getName(), null // 不设置密码,使用默认密码 ); // 更新用户的生日信息 if (input.getPlayerInfo().getBirthDate() != null) { user.setBirthday(input.getPlayerInfo().getBirthDate()); user = userService.save(user); log.info("更新用户生日信息成功,用户ID: {}", user.getId()); } return user; } catch (Exception e) { log.error("创建或更新用户记录时发生错误", e); throw new RuntimeException("创建或更新用户记录失败", e); } } /** * 更新现有选手关联的用户信息 */ private void updateUserInfo(Player existingPlayer, ActivityRegistrationInput input) { try { if (existingPlayer.getUserId() != null && existingPlayer.getUserId() > 0) { Optional userOpt = userService.findById(existingPlayer.getUserId()); if (userOpt.isPresent()) { User user = userOpt.get(); // 更新用户姓名 user.setName(input.getPlayerInfo().getName()); // 更新生日信息 if (input.getPlayerInfo().getBirthDate() != null) { user.setBirthday(input.getPlayerInfo().getBirthDate()); } userService.save(user); log.info("更新现有用户信息成功,用户ID: {}", user.getId()); } else { log.warn("未找到选手关联的用户记录,选手ID: {}, 用户ID: {}", existingPlayer.getId(), existingPlayer.getUserId()); } } else { log.info("选手未关联用户记录,选手ID: {}", existingPlayer.getId()); } } catch (Exception e) { log.error("更新用户信息时发生错误", e); // 不抛出异常,避免影响选手信息的更新 } } /** * 保存媒体文件 */ private void saveMediaFiles(Long activityPlayerId, List mediaFiles) { try { for (MediaFileInput mediaFile : mediaFiles) { Media media = new Media(); media.setName(mediaFile.getName()); media.setPath(mediaFile.getPath()); media.setFileExt(mediaFile.getFileExt()); media.setFileSize(mediaFile.getFileSize()); media.setMediaType(mediaFile.getMediaType()); media.setTargetType(MediaTargetType.ACTIVITY_PLAYER_SUBMISSION.getValue()); // 活动选手媒体文件 media.setTargetId(activityPlayerId); media.setState(1); // 1表示有效状态 // BaseEntity会自动设置createTime和updateTime mediaRepository.save(media); log.info("媒体文件保存成功,文件名: {}", mediaFile.getName()); } } catch (Exception e) { log.error("保存媒体文件时发生错误", e); } } /** * 获取玩家在指定活动中的报名状态 * @param activityId 活动ID * @return 报名状态信息 */ public PlayerRegistrationResponse getPlayerRegistration(Long activityId) { try { // 获取当前用户ID Long currentUserId = userContextUtil.getCurrentUserId(); if (currentUserId == null) { log.warn("未找到当前用户信息"); return null; } // 查找当前用户对应的Player记录 Optional playerOpt = playerRepository.findByUserId(currentUserId); if (!playerOpt.isPresent()) { log.info("用户 {} 尚未创建Player记录", currentUserId); return null; } Player player = playerOpt.get(); // 查找该玩家在指定活动中的报名记录 Optional activityPlayerOpt = activityPlayerRepository .findByActivityIdAndPlayerId(activityId, player.getId()); if (!activityPlayerOpt.isPresent()) { log.info("玩家 {} 未在活动 {} 中报名", player.getId(), activityId); return null; } ActivityPlayer activityPlayer = activityPlayerOpt.get(); // 构建响应对象 PlayerRegistrationResponse response = new PlayerRegistrationResponse(); response.setId(activityPlayer.getId()); response.setStatus(activityPlayer.getState()); response.setRegistrationTime(activityPlayer.getCreateTime() != null ? activityPlayer.getCreateTime().toString() : null); response.setReviewStatus(activityPlayer.getState()); // 使用state作为审核状态 response.setReviewComment(activityPlayer.getDescription()); // 使用description作为审核备注 log.info("成功获取玩家 {} 在活动 {} 中的报名状态", player.getId(), activityId); return response; } catch (Exception e) { log.error("获取玩家报名状态时发生错误,活动ID: {}", activityId, e); throw new RuntimeException("获取报名状态失败", e); } } /** * 审核通过 */ public Boolean approveActivityPlayer(Long activityPlayerId, String feedback) { try { Optional activityPlayerOpt = activityPlayerRepository.findById(activityPlayerId); if (!activityPlayerOpt.isPresent()) { throw new RuntimeException("报名记录不存在"); } ActivityPlayer activityPlayer = activityPlayerOpt.get(); activityPlayer.setState(1); // 1=审核通过 activityPlayer.setFeedback(feedback); activityPlayerRepository.save(activityPlayer); // 创建审核通过消息 messageService.createApprovalMessage( activityPlayerId, activityPlayer.getPlayerId(), activityPlayer.getProjectName() ); log.info("审核通过成功,activityPlayerId: {}", activityPlayerId); return true; } catch (Exception e) { log.error("审核通过失败,activityPlayerId: {}", activityPlayerId, e); throw new RuntimeException("审核通过失败", e); } } /** * 审核驳回 */ public Boolean rejectActivityPlayer(Long activityPlayerId, String feedback) { try { Optional activityPlayerOpt = activityPlayerRepository.findById(activityPlayerId); if (!activityPlayerOpt.isPresent()) { throw new RuntimeException("报名记录不存在"); } ActivityPlayer activityPlayer = activityPlayerOpt.get(); activityPlayer.setState(2); // 2=审核驳回 activityPlayer.setFeedback(feedback); activityPlayerRepository.save(activityPlayer); // 创建审核驳回消息 messageService.createRejectionMessage( activityPlayerId, activityPlayer.getPlayerId(), activityPlayer.getProjectName() ); log.info("审核驳回成功,activityPlayerId: {}", activityPlayerId); return true; } catch (Exception e) { log.error("审核驳回失败,activityPlayerId: {}", activityPlayerId, e); throw new RuntimeException("审核驳回失败", e); } } /** * 更新报名信息 */ public ActivityRegistrationResponse updateActivityRegistration(Long activityPlayerId, ActivityRegistrationInput input) { try { log.info("开始更新报名信息,报名ID: {}", activityPlayerId); // 1. 查找现有报名记录 Optional activityPlayerOpt = activityPlayerRepository.findById(activityPlayerId); if (!activityPlayerOpt.isPresent()) { throw new RuntimeException("报名记录不存在"); } ActivityPlayer activityPlayer = activityPlayerOpt.get(); // 2. 更新选手信息 Player player = playerRepository.findById(activityPlayer.getPlayerId()).orElse(null); if (player != null) { player.setName(input.getPlayerInfo().getName()); if (input.getPlayerInfo().getGender() != null) { player.setGender(input.getPlayerInfo().getGender()); } if (input.getPlayerInfo().getEducation() != null) { player.setEducation(input.getPlayerInfo().getEducation()); } if (input.getPlayerInfo().getIntroduction() != null) { player.setIntroduction(input.getPlayerInfo().getIntroduction()); } if (input.getPlayerInfo().getDescription() != null) { player.setDescription(input.getPlayerInfo().getDescription()); } playerRepository.save(player); // 更新用户信息 updateUserInfo(player, input); } // 3. 更新报名记录基本信息 if (input.getProjectName() != null) { activityPlayer.setProjectName(input.getProjectName()); } if (input.getDescription() != null) { activityPlayer.setDescription(input.getDescription()); } if (input.getRegionId() != null) { activityPlayer.setRegionId(input.getRegionId()); } activityPlayerRepository.save(activityPlayer); // 4. 处理头像更新 if (input.getPlayerInfo().getAvatarMediaId() != null && !input.getPlayerInfo().getAvatarMediaId().isEmpty()) { // 保存新头像 savePlayerAvatarMedia(player.getId(), input.getPlayerInfo().getAvatarMediaId()); } // 5. 处理比赛图片和视频更新 if (input.getMediaFiles() != null) { // 删除旧的比赛图片和视频记录 deleteOldSubmissionMedia(activityPlayerId); // 保存新的比赛图片和视频 saveMediaFiles(activityPlayerId, input.getMediaFiles()); } // 6. 处理附件更新 if (input.getAttachmentMediaIds() != null) { // 删除旧附件记录 deleteOldAttachmentMedia(activityPlayerId); // 保存新附件 saveAttachmentMediaRecords(activityPlayerId, input.getAttachmentMediaIds()); } log.info("更新报名信息成功,报名ID: {}", activityPlayerId); ActivityRegistrationResponse response = new ActivityRegistrationResponse(); response.setSuccess(true); response.setMessage("更新报名信息成功"); response.setRegistrationId(activityPlayerId); response.setPlayerId(player.getId()); response.setUserId(player.getUserId()); response.setActivityPlayerId(activityPlayerId); return response; } catch (Exception e) { log.error("更新报名信息失败,报名ID: {}", activityPlayerId, e); throw new RuntimeException("更新报名信息失败: " + e.getMessage(), e); } } /** * 删除旧的比赛图片和视频记录 */ private void deleteOldSubmissionMedia(Long activityPlayerId) { try { List oldSubmissionMedia = mediaRepository.findByTargetTypeAndTargetIdAndState( MediaTargetType.ACTIVITY_PLAYER_SUBMISSION.getValue(), activityPlayerId, 1); for (Media media : oldSubmissionMedia) { media.setState(0); // 设置为删除状态 mediaRepository.save(media); } log.info("删除旧比赛图片/视频记录成功,报名ID: {}, 删除数量: {}", activityPlayerId, oldSubmissionMedia.size()); } catch (Exception e) { log.error("删除旧比赛图片/视频记录失败,报名ID: {}", activityPlayerId, e); } } /** * 删除旧的附件媒体记录 */ private void deleteOldAttachmentMedia(Long activityPlayerId) { try { List oldAttachments = mediaRepository.findByTargetTypeAndTargetIdAndState( 5, activityPlayerId, 1); // target_type=5 是附件 for (Media oldAttachment : oldAttachments) { oldAttachment.setState(0); // 设置为删除状态 mediaRepository.save(oldAttachment); } log.info("删除旧附件记录成功,报名ID: {}, 删除数量: {}", activityPlayerId, oldAttachments.size()); } catch (Exception e) { log.error("删除旧附件记录失败,报名ID: {}", activityPlayerId, e); } } /** * 更新审核意见 */ public Boolean updateFeedback(Long activityPlayerId, String feedback) { try { Optional activityPlayerOpt = activityPlayerRepository.findById(activityPlayerId); if (!activityPlayerOpt.isPresent()) { throw new RuntimeException("报名记录不存在"); } ActivityPlayer activityPlayer = activityPlayerOpt.get(); activityPlayer.setFeedback(feedback); activityPlayerRepository.save(activityPlayer); log.info("更新审核意见成功,activityPlayerId: {}", activityPlayerId); return true; } catch (Exception e) { log.error("更新审核意见失败,activityPlayerId: {}", activityPlayerId, e); throw new RuntimeException("更新审核意见失败", e); } } /** * 保存用户头像 * 将已上传的头像媒体文件关联到用户 */ private void savePlayerAvatar(Long playerId, Long avatarMediaId) { try { // 获取player对应的用户ID Optional playerOpt = playerRepository.findById(playerId); if (!playerOpt.isPresent()) { log.warn("未找到学员记录,学员ID: {}", playerId); return; } Player player = playerOpt.get(); Long userId = player.getUserId(); if (userId == null) { log.warn("学员未关联用户,学员ID: {}", playerId); return; } // 查找现有的头像记录并删除(确保一个用户只有一个头像) mediaRepository.deleteByTargetTypeAndTargetId(MediaTargetType.USER_AVATAR.getValue(), userId); // 更新媒体文件的target信息 Media avatarMedia = mediaRepository.findById(avatarMediaId).orElse(null); if (avatarMedia != null) { avatarMedia.setTargetType(MediaTargetType.USER_AVATAR.getValue()); avatarMedia.setTargetId(userId); mediaRepository.save(avatarMedia); log.info("用户头像保存成功,用户ID: {}, 媒体ID: {}", userId, avatarMediaId); } else { log.warn("未找到头像媒体文件,媒体ID: {}", avatarMediaId); } } catch (Exception e) { log.error("保存用户头像时发生错误,学员ID: {}, 媒体ID: {}", playerId, avatarMediaId, e); } } /** * 保存附件媒体文件 * 将已上传的附件媒体文件关联到活动报名记录 */ private void saveAttachmentMediaFiles(Long activityPlayerId, List attachmentMediaIds) { try { for (Long mediaId : attachmentMediaIds) { Media attachmentMedia = mediaRepository.findById(mediaId).orElse(null); if (attachmentMedia != null) { attachmentMedia.setTargetType(MediaTargetType.ACTIVITY_PLAYER_SUBMISSION.getValue()); attachmentMedia.setTargetId(activityPlayerId); mediaRepository.save(attachmentMedia); log.info("附件媒体文件保存成功,报名ID: {}, 媒体ID: {}", activityPlayerId, mediaId); } else { log.warn("未找到附件媒体文件,媒体ID: {}", mediaId); } } } catch (Exception e) { log.error("保存附件媒体文件时发生错误,报名ID: {}", activityPlayerId, e); } } /** * 保存选手头像媒体记录 * 使用新的媒体API保存头像媒体记录 */ private void savePlayerAvatarMedia(Long playerId, String avatarMediaId) { try { log.info("开始保存选手头像媒体记录,选手ID: {}, 媒体ID: {}", playerId, avatarMediaId); MediaSaveInput input = new MediaSaveInput(); input.setTargetType("player"); input.setTargetId(playerId); input.setPath(avatarMediaId); // COS路径 input.setFileName("avatar.jpg"); // 默认头像文件名 input.setFileExt("jpg"); // 文件扩展名 input.setFileSize(0L); // 文件大小暂时设为0 input.setMediaType(1); // 头像类型 mediaV2Service.saveMedia(input); log.info("选手头像媒体记录保存成功,选手ID: {}", playerId); } catch (Exception e) { log.error("保存选手头像媒体记录时发生错误,选手ID: {}, 媒体ID: {}", playerId, avatarMediaId, e); } } /** * 保存附件媒体记录 * 使用新的媒体API保存附件媒体记录 */ private void saveAttachmentMediaRecords(Long activityPlayerId, List attachmentMediaIds) { try { log.info("开始保存附件媒体记录,报名ID: {}, 附件数量: {}", activityPlayerId, attachmentMediaIds.size()); for (String mediaId : attachmentMediaIds) { MediaSaveInput input = new MediaSaveInput(); input.setTargetType("activity_player"); input.setTargetId(activityPlayerId); input.setPath(mediaId); // COS路径 input.setFileName("attachment"); // 默认附件文件名 input.setFileExt("jpg"); // 文件扩展名 input.setFileSize(0L); // 文件大小暂时设为0 input.setMediaType(2); // 附件类型 mediaV2Service.saveMedia(input); log.info("附件媒体记录保存成功,报名ID: {}, 媒体ID: {}", activityPlayerId, mediaId); } } catch (Exception e) { log.error("保存附件媒体记录时发生错误,报名ID: {}", activityPlayerId, e); } } }