package com.rongyichuang.player.service;
|
|
import com.rongyichuang.player.dto.response.*;
|
import com.rongyichuang.player.dto.response.RegionInfoResponse;
|
import com.rongyichuang.rating.dto.response.RatingItemResponse;
|
import com.rongyichuang.rating.entity.RatingScheme;
|
import com.rongyichuang.rating.repository.RatingSchemeRepository;
|
import com.rongyichuang.common.entity.Media;
|
import com.rongyichuang.common.enums.MediaTargetType;
|
import com.rongyichuang.common.repository.MediaRepository;
|
import com.rongyichuang.common.dto.response.MediaResponse;
|
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.Query;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.util.List;
|
import java.util.ArrayList;
|
import java.util.Map;
|
import java.util.HashMap;
|
import java.util.stream.Collectors;
|
|
/**
|
* 比赛报名详情服务(用于评分页面)
|
*/
|
@Service
|
public class ActivityPlayerDetailService {
|
|
private static final Logger log = LoggerFactory.getLogger(ActivityPlayerDetailService.class);
|
|
@PersistenceContext
|
private EntityManager em;
|
|
private final MediaRepository mediaRepository;
|
private final RatingSchemeRepository ratingSchemeRepository;
|
|
@Value("${app.media-url}")
|
private String mediaBaseUrl;
|
|
public ActivityPlayerDetailService(MediaRepository mediaRepository,
|
RatingSchemeRepository ratingSchemeRepository) {
|
this.mediaRepository = mediaRepository;
|
this.ratingSchemeRepository = ratingSchemeRepository;
|
}
|
|
/**
|
* 获取比赛报名详情(用于评分)
|
* @param activityPlayerId 报名记录ID
|
* @return 报名详情
|
*/
|
public ActivityPlayerDetailResponse getDetailForRating(Long activityPlayerId) {
|
log.info("获取报名详情用于评分,activityPlayerId: {}", activityPlayerId);
|
|
// 查询基本信息,包含区域信息
|
String sql = """
|
SELECT ap.id as ap_id, ap.description as ap_description, ap.activity_id, ap.region_id,
|
ap.project_name, ap.feedback, ap.state as ap_state,
|
p.id as player_id, p.name as player_name, p.phone, p.description as player_desc,
|
p.gender, u.birthday, p.education, p.introduction, u.id as user_id,
|
a.name as activity_name, a.rating_scheme_id,
|
r.id as region_id, r.name as region_name, r.full_path as region_path
|
FROM t_activity_player ap
|
JOIN t_player p ON p.id = ap.player_id
|
JOIN t_user u ON u.id = p.user_id
|
JOIN t_activity a ON a.id = ap.activity_id
|
LEFT JOIN t_region r ON r.id = ap.region_id
|
WHERE ap.id = ?
|
""";
|
|
@SuppressWarnings("unchecked")
|
Query query = em.createNativeQuery(sql);
|
query.setParameter(1, activityPlayerId);
|
|
// 使用 Tuple 来获取命名字段
|
query.unwrap(org.hibernate.query.NativeQuery.class).setTupleTransformer(
|
(tuple, aliases) -> {
|
Map<String, Object> result = new HashMap<>();
|
for (int i = 0; i < aliases.length; i++) {
|
result.put(aliases[i], tuple[i]);
|
}
|
return result;
|
}
|
);
|
|
@SuppressWarnings("unchecked")
|
List<Map<String, Object>> results = query.getResultList();
|
|
if (results.isEmpty()) {
|
log.warn("未找到报名记录,activityPlayerId: {}", activityPlayerId);
|
return null;
|
}
|
|
Map<String, Object> row = results.get(0);
|
ActivityPlayerDetailResponse response = new ActivityPlayerDetailResponse();
|
response.setId(activityPlayerId);
|
response.setDescription(row.get("ap_description") != null ? row.get("ap_description").toString() : "");
|
response.setProjectName(row.get("project_name") != null ? row.get("project_name").toString() : "");
|
response.setFeedback(row.get("feedback") != null ? row.get("feedback").toString() : "");
|
|
Object stateObj = row.get("ap_state");
|
if (stateObj != null) {
|
if (stateObj instanceof Number) {
|
response.setState(((Number) stateObj).intValue());
|
} else {
|
log.warn("状态类型不匹配: {}, 类型: {}", stateObj, stateObj.getClass().getName());
|
response.setState(Integer.valueOf(stateObj.toString()));
|
}
|
} else {
|
response.setState(0);
|
}
|
response.setActivityName(row.get("activity_name") != null ? row.get("activity_name").toString() : "");
|
|
// 构建学员信息
|
PlayerInfoResponse playerInfo = new PlayerInfoResponse();
|
Object playerIdObj = row.get("player_id");
|
if (playerIdObj != null) {
|
if (playerIdObj instanceof Number) {
|
playerInfo.setId(((Number) playerIdObj).longValue());
|
} else {
|
log.warn("学员ID类型不匹配: {}, 类型: {}", playerIdObj, playerIdObj.getClass().getName());
|
playerInfo.setId(Long.valueOf(playerIdObj.toString()));
|
}
|
} else {
|
playerInfo.setId(null);
|
}
|
playerInfo.setName(row.get("player_name") != null ? row.get("player_name").toString() : "");
|
playerInfo.setPhone(row.get("phone") != null ? row.get("phone").toString() : "");
|
playerInfo.setDescription(row.get("player_desc") != null ? row.get("player_desc").toString() : "");
|
|
Object genderObj = row.get("gender");
|
if (genderObj != null) {
|
if (genderObj instanceof Number) {
|
playerInfo.setGender(((Number) genderObj).intValue());
|
} else {
|
log.warn("性别类型不匹配: {}, 类型: {}", genderObj, genderObj.getClass().getName());
|
playerInfo.setGender(Integer.valueOf(genderObj.toString()));
|
}
|
} else {
|
playerInfo.setGender(null);
|
}
|
|
Object birthdayObj = row.get("birthday");
|
playerInfo.setBirthday(birthdayObj != null ?
|
(birthdayObj instanceof java.sql.Date ? ((java.sql.Date) birthdayObj).toString() : birthdayObj.toString()) : null);
|
playerInfo.setEducation(row.get("education") != null ? row.get("education").toString() : "");
|
playerInfo.setIntroduction(row.get("introduction") != null ? row.get("introduction").toString() : "");
|
|
// 构建区域信息
|
Object regionIdObj = row.get("region_id");
|
if (regionIdObj != null) {
|
RegionInfoResponse regionInfo = new RegionInfoResponse();
|
if (regionIdObj instanceof Number) {
|
regionInfo.setId(((Number) regionIdObj).longValue());
|
} else {
|
log.warn("区域ID类型不匹配: {}, 类型: {}", regionIdObj, regionIdObj.getClass().getName());
|
regionInfo.setId(Long.valueOf(regionIdObj.toString()));
|
}
|
regionInfo.setName(row.get("region_name") != null ? row.get("region_name").toString() : "");
|
regionInfo.setFullPath(row.get("region_path") != null ? row.get("region_path").toString() : "");
|
response.setRegionInfo(regionInfo);
|
log.info("找到区域信息: {}", regionInfo.getName());
|
}
|
|
// 查询用户头像(使用USER_AVATAR关联到用户)
|
Object userIdObj = row.get("user_id");
|
log.info("调试:从查询结果中获取的user_id: {}", userIdObj);
|
if (userIdObj != null) {
|
Long userId;
|
if (userIdObj instanceof Number) {
|
userId = ((Number) userIdObj).longValue();
|
} else {
|
userId = Long.valueOf(userIdObj.toString());
|
}
|
log.info("调试:解析后的userId: {}", userId);
|
|
List<Media> avatarMedias = mediaRepository.findByTargetTypeAndTargetIdAndState(
|
MediaTargetType.USER_AVATAR.getValue(), userId, 1);
|
log.info("调试:查询到的头像媒体数量: {}", avatarMedias.size());
|
if (!avatarMedias.isEmpty()) {
|
Media avatar = avatarMedias.get(0);
|
String avatarUrl = buildFullMediaUrl(avatar.getPath());
|
playerInfo.setAvatarUrl(avatarUrl);
|
// 设置avatar对象
|
playerInfo.setAvatar(convertToMediaResponse(avatar));
|
log.info("找到用户头像: {}", avatarUrl);
|
} else {
|
log.info("调试:未找到用户头像,userId: {}, targetType: {}", userId, MediaTargetType.USER_AVATAR.getValue());
|
}
|
} else {
|
log.warn("调试:user_id为null");
|
}
|
response.setPlayerInfo(playerInfo);
|
|
// 查询提交的资料(使用枚举常量表示参赛报名资料类型)
|
List<Media> submissionMedias = mediaRepository.findByTargetTypeAndTargetIdAndState(
|
MediaTargetType.ACTIVITY_PLAYER_SUBMISSION.getValue(), activityPlayerId, 1);
|
List<SubmissionMediaResponse> submissionFiles = submissionMedias.stream()
|
.map(this::convertToSubmissionMedia)
|
.collect(Collectors.toList());
|
response.setSubmissionFiles(submissionFiles);
|
log.info("找到提交资料 {} 个", submissionFiles.size());
|
|
// 查询评分模板
|
Object ratingSchemeIdObj = row.get("rating_scheme_id");
|
Long ratingSchemeId = ratingSchemeIdObj != null ? ((Number) ratingSchemeIdObj).longValue() : null;
|
if (ratingSchemeId != null) {
|
RatingFormResponse ratingForm = buildRatingForm(ratingSchemeId);
|
response.setRatingForm(ratingForm);
|
}
|
|
return response;
|
}
|
|
/**
|
* 转换媒体文件为提交资料响应
|
*/
|
private SubmissionMediaResponse convertToSubmissionMedia(Media media) {
|
SubmissionMediaResponse response = new SubmissionMediaResponse();
|
response.setId(media.getId());
|
response.setName(media.getName());
|
response.setUrl(buildFullMediaUrl(media.getPath()));
|
response.setFileExt(media.getFileExt());
|
response.setFileSize(media.getFileSize() != null ? media.getFileSize().longValue() : null);
|
response.setMediaType(media.getMediaType());
|
response.setThumbUrl(buildFullMediaUrl(media.getThumbPath()));
|
return response;
|
}
|
|
/**
|
* 构建评分表单
|
*/
|
private RatingFormResponse buildRatingForm(Long ratingSchemeId) {
|
log.info("构建评分表单,ratingSchemeId: {}", ratingSchemeId);
|
|
RatingScheme scheme = ratingSchemeRepository.findById(ratingSchemeId).orElse(null);
|
if (scheme == null) {
|
log.warn("未找到评分模板,ratingSchemeId: {}", ratingSchemeId);
|
return null;
|
}
|
|
RatingFormResponse response = new RatingFormResponse();
|
response.setSchemeId(scheme.getId());
|
response.setSchemeName(scheme.getName());
|
response.setTotalMaxScore(scheme.getTotalScore());
|
|
// 转换评分项目
|
if (scheme.getItems() != null) {
|
List<RatingItemResponse> items = scheme.getItems().stream()
|
.map(RatingItemResponse::new)
|
.collect(Collectors.toList());
|
response.setItems(items);
|
}
|
|
log.info("评分模板构建完成,包含 {} 个评分项目",
|
response.getItems() != null ? response.getItems().size() : 0);
|
|
return response;
|
}
|
|
/**
|
* 转换媒体文件为MediaResponse
|
*/
|
private MediaResponse convertToMediaResponse(Media media) {
|
MediaResponse response = new MediaResponse();
|
response.setId(media.getId());
|
response.setName(media.getName());
|
response.setPath(media.getPath());
|
response.setFileSize(media.getFileSize());
|
response.setFileExt(media.getFileExt());
|
response.setThumbPath(media.getThumbPath());
|
response.setDuration(media.getDuration());
|
response.setDescription(media.getDescription());
|
response.setTargetType(media.getTargetType());
|
response.setTargetId(media.getTargetId());
|
response.setMediaType(media.getMediaType());
|
|
// 设置完整URL
|
response.setFullUrl(buildFullMediaUrl(media.getPath()));
|
response.setFullThumbUrl(buildFullMediaUrl(media.getThumbPath()));
|
|
return response;
|
}
|
|
private String buildFullMediaUrl(String path) {
|
if (!StringUtils.hasText(path)) {
|
return null;
|
}
|
|
// 如果已经是完整URL,直接返回
|
if (path.startsWith("http://") || path.startsWith("https://")) {
|
return path;
|
}
|
|
// 如果没有配置mediaBaseUrl,返回原路径
|
if (!StringUtils.hasText(mediaBaseUrl)) {
|
return path;
|
}
|
|
// 拼接完整URL
|
String baseUrl = mediaBaseUrl.endsWith("/") ? mediaBaseUrl : mediaBaseUrl + "/";
|
String relativePath = path.startsWith("/") ? path.substring(1) : path;
|
return baseUrl + relativePath;
|
}
|
}
|