package com.rongyichuang.judge.service;
|
|
import com.rongyichuang.judge.dto.request.JudgeInput;
|
import com.rongyichuang.judge.dto.response.JudgeResponse;
|
import com.rongyichuang.judge.entity.Judge;
|
import com.rongyichuang.tag.entity.Tag;
|
import com.rongyichuang.judge.repository.JudgeRepository;
|
import com.rongyichuang.common.entity.Media;
|
import com.rongyichuang.common.repository.MediaRepository;
|
import com.rongyichuang.common.dto.request.MediaInput;
|
import com.rongyichuang.common.dto.response.MediaResponse;
|
import com.rongyichuang.common.service.MediaService;
|
import com.rongyichuang.common.exception.BusinessException;
|
import com.rongyichuang.common.enums.MediaTargetType;
|
import com.rongyichuang.tag.repository.TagRepository;
|
import com.rongyichuang.user.service.UserService;
|
import com.rongyichuang.user.entity.User;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.util.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.util.Collections;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class JudgeService {
|
|
private static final Logger log = LoggerFactory.getLogger(JudgeService.class);
|
|
private final JudgeRepository judgeRepository;
|
private final TagRepository tagRepository;
|
private final MediaRepository mediaRepository;
|
private final MediaService mediaService;
|
private final UserService userService;
|
|
@Value("${app.media-url}")
|
private String mediaBaseUrl;
|
|
public JudgeService(JudgeRepository judgeRepository, TagRepository tagRepository,
|
MediaRepository mediaRepository, MediaService mediaService,
|
UserService userService) {
|
this.judgeRepository = judgeRepository;
|
this.tagRepository = tagRepository;
|
this.mediaRepository = mediaRepository;
|
this.mediaService = mediaService;
|
this.userService = userService;
|
}
|
|
public List<JudgeResponse> findAll() {
|
return judgeRepository.findAll(Sort.by(Sort.Direction.DESC, "updateTime")).stream()
|
.map(this::convertToResponse)
|
.collect(Collectors.toList());
|
}
|
|
public List<JudgeResponse> findByName(String name) {
|
return judgeRepository.findByNameContaining(name).stream()
|
.map(this::convertToResponse)
|
.collect(Collectors.toList());
|
}
|
|
public JudgeResponse findById(Long id) {
|
return judgeRepository.findById(id)
|
.map(this::convertToResponse)
|
.orElse(null);
|
}
|
|
@Transactional
|
public JudgeResponse save(JudgeInput input) {
|
Judge judge;
|
User user;
|
|
// 处理User表逻辑
|
if (input.getPassword() != null && !input.getPassword().trim().isEmpty() && !"••••••••".equals(input.getPassword())) {
|
// 有密码且不是占位符时,创建或更新用户(包含密码)
|
user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), input.getPassword());
|
} else {
|
// 无密码或是占位符时,只更新用户基本信息(不更新密码)
|
user = userService.findOrCreateUserByPhone(input.getPhone(), input.getName(), null);
|
}
|
|
if (input.getId() != null) {
|
judge = judgeRepository.findById(input.getId())
|
.orElseThrow(() -> new BusinessException("评委不存在"));
|
} else {
|
judge = new Judge();
|
// 新增评委时检查手机号是否已存在
|
if (judgeRepository.existsByPhone(input.getPhone())) {
|
throw new BusinessException("PHONE_EXISTS", "手机号码已存在,请使用其他手机号码");
|
}
|
}
|
|
judge.setName(input.getName());
|
judge.setPhone(input.getPhone());
|
judge.setGender(input.getGender());
|
judge.setDescription(input.getDescription());
|
judge.setTitle(input.getTitle());
|
judge.setCompany(input.getCompany());
|
judge.setIntroduction(input.getIntroduction());
|
judge.setUserId(user.getId()); // 设置关联的用户ID
|
// 头像信息通过t_media表的target_type和target_id关联
|
|
// 设置专业标签
|
if (input.getMajorIds() != null && !input.getMajorIds().isEmpty()) {
|
List<Tag> specialtiesList = tagRepository.findAllById(input.getMajorIds());
|
judge.setSpecialties(new HashSet<>(specialtiesList));
|
} else {
|
judge.setSpecialties(Collections.emptySet());
|
}
|
|
Judge savedJudge = judgeRepository.save(judge);
|
return convertToResponse(savedJudge);
|
}
|
|
@Transactional
|
public void delete(Long id) {
|
Judge judge = judgeRepository.findById(id)
|
.orElseThrow(() -> new BusinessException("评委不存在"));
|
judgeRepository.delete(judge);
|
}
|
|
private JudgeResponse convertToResponse(Judge judge) {
|
log.info("=== convertToResponse called for judge: {} (ID: {})", judge.getName(), judge.getId());
|
|
JudgeResponse response = new JudgeResponse();
|
response.setId(judge.getId());
|
response.setName(judge.getName());
|
response.setPhone(judge.getPhone());
|
response.setGender(judge.getGender());
|
response.setDescription(judge.getDescription());
|
response.setTitle(judge.getTitle());
|
response.setCompany(judge.getCompany());
|
response.setIntroduction(judge.getIntroduction());
|
|
// 查询头像信息:使用枚举常量表示评委头像类型
|
log.info("=== Querying media for judge ID: {}", judge.getId());
|
List<Media> avatarMedias = mediaRepository.findByTargetTypeAndTargetIdAndState(
|
MediaTargetType.JUDGE_AVATAR.getValue(), judge.getId(), 1);
|
log.info("=== Found {} media records", avatarMedias.size());
|
|
if (!avatarMedias.isEmpty()) {
|
// 取第一个媒体作为头像
|
Media avatarMedia = avatarMedias.get(0);
|
String avatarPath = avatarMedia.getPath();
|
String avatarUrl = buildFullMediaUrl(avatarPath);
|
log.info("=== Setting avatarUrl: {}", avatarUrl);
|
response.setAvatarUrl(avatarUrl);
|
} else {
|
log.info("=== No media found, avatarUrl will be null");
|
}
|
|
if (judge.getSpecialties() != null) {
|
response.setSpecialties(judge.getSpecialties().stream()
|
.map(tag -> {
|
JudgeResponse.TagResponse tagResponse = new JudgeResponse.TagResponse();
|
tagResponse.setId(tag.getId());
|
tagResponse.setName(tag.getName());
|
tagResponse.setCode(tag.getCode());
|
return tagResponse;
|
})
|
.collect(Collectors.toList()));
|
}
|
|
return response;
|
}
|
|
/**
|
* 构建完整的媒体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;
|
}
|
|
/**
|
* 保存媒体信息
|
*/
|
public MediaResponse saveMediaInfo(MediaInput input) {
|
Media media = mediaService.saveMedia(
|
input.getName(),
|
input.getPath(),
|
input.getFileSize(),
|
input.getFileExt(),
|
input.getMediaType(),
|
input.getTargetType(),
|
input.getTargetId()
|
);
|
|
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.setMediaType(media.getMediaType());
|
response.setTargetType(media.getTargetType());
|
response.setTargetId(media.getTargetId());
|
|
return response;
|
}
|
}
|