lrj
3 天以前 7ba080d35812e6db7bd5aa8f88161c02653eb6c1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
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;
    }
}