forked from baskbuddy/zhangshun
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
5.6 KiB
122 lines
5.6 KiB
package com.mydreamjob.preference;
|
|
|
|
import com.mydreamjob.auth.User;
|
|
import com.mydreamjob.auth.UserRepository;
|
|
import com.mydreamjob.common.exception.BusinessException;
|
|
import com.mydreamjob.common.exception.ErrorCode;
|
|
import com.mydreamjob.candidatescore.refresh.CandidateScoringRefreshRequestService;
|
|
import com.mydreamjob.preference.dto.StudentPreferenceRequest;
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.mydreamjob.security.UserRoleGuard;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class PreferenceService {
|
|
|
|
private final com.mydreamjob.security.UserRoleGuard userRoleGuard;
|
|
private final StudentPreferenceRepository preferenceRepository;
|
|
private final UserRepository userRepository;
|
|
/** R01-D4-1:求职偏好更新后登记评分快照刷新(COMPLIANCE 维度)。 */
|
|
private final CandidateScoringRefreshRequestService scoringRefreshRequestService;
|
|
private static final ObjectMapper mapper = new ObjectMapper();
|
|
|
|
// ── 角色校验 ──────────────────────────────────────────────
|
|
|
|
public void assertStudentRole(Long userId) {
|
|
userRoleGuard.requireStudent(userId);
|
|
}
|
|
|
|
// ── 查询 ──────────────────────────────────────────────────
|
|
|
|
public Map<String, Object> getPreferences(Long studentUserId) {
|
|
assertStudentRole(studentUserId);
|
|
return preferenceRepository.findByStudentUserId(studentUserId)
|
|
.map(this::toView)
|
|
.orElse(emptyView());
|
|
}
|
|
|
|
// ── 保存/更新 ────────────────────────────────────────────
|
|
|
|
@Transactional
|
|
public Map<String, Object> savePreferences(Long studentUserId, StudentPreferenceRequest req) {
|
|
assertStudentRole(studentUserId);
|
|
|
|
StudentPreference pref = preferenceRepository.findByStudentUserId(studentUserId)
|
|
.orElse(StudentPreference.builder()
|
|
.studentUserId(studentUserId)
|
|
.remoteAllowed(false)
|
|
.build());
|
|
|
|
if (req.getExpectedSalaryMin() != null) pref.setExpectedSalaryMin(req.getExpectedSalaryMin());
|
|
if (req.getExpectedSalaryMax() != null) pref.setExpectedSalaryMax(req.getExpectedSalaryMax());
|
|
if (req.getPreferredCities() != null) pref.setPreferredCities(toJson(req.getPreferredCities()));
|
|
if (req.getEmploymentTypes() != null) pref.setEmploymentTypes(toJson(req.getEmploymentTypes()));
|
|
if (req.getPreferredIndustries() != null) pref.setPreferredIndustries(toJson(req.getPreferredIndustries()));
|
|
if (req.getPreferredJobTypes() != null) pref.setPreferredJobTypes(toJson(req.getPreferredJobTypes()));
|
|
if (req.getRemoteAllowed() != null) pref.setRemoteAllowed(req.getRemoteAllowed());
|
|
|
|
StudentPreference saved = preferenceRepository.save(pref);
|
|
// R01-D4-1:偏好更新影响 COMPLIANCE 维度 → 登记当前周期刷新。
|
|
scoringRefreshRequestService.requestRefresh(studentUserId, LocalDateTime.now());
|
|
return toView(saved);
|
|
}
|
|
|
|
// ── 视图 ──────────────────────────────────────────────────
|
|
|
|
private Map<String, Object> toView(StudentPreference pref) {
|
|
Map<String, Object> view = new HashMap<>();
|
|
view.put("id", pref.getId());
|
|
view.put("studentUserId", pref.getStudentUserId());
|
|
view.put("expectedSalaryMin", pref.getExpectedSalaryMin());
|
|
view.put("expectedSalaryMax", pref.getExpectedSalaryMax());
|
|
view.put("preferredCities", fromJson(pref.getPreferredCities()));
|
|
view.put("employmentTypes", fromJson(pref.getEmploymentTypes()));
|
|
view.put("preferredIndustries", fromJson(pref.getPreferredIndustries()));
|
|
view.put("preferredJobTypes", fromJson(pref.getPreferredJobTypes()));
|
|
view.put("remoteAllowed", pref.getRemoteAllowed());
|
|
view.put("createdAt", pref.getCreatedAt());
|
|
view.put("updatedAt", pref.getUpdatedAt());
|
|
return view;
|
|
}
|
|
|
|
private Map<String, Object> emptyView() {
|
|
Map<String, Object> view = new HashMap<>();
|
|
view.put("expectedSalaryMin", null);
|
|
view.put("expectedSalaryMax", null);
|
|
view.put("preferredCities", List.of());
|
|
view.put("employmentTypes", List.of());
|
|
view.put("preferredIndustries", List.of());
|
|
view.put("preferredJobTypes", List.of());
|
|
view.put("remoteAllowed", false);
|
|
return view;
|
|
}
|
|
|
|
private String toJson(List<String> list) {
|
|
try {
|
|
return mapper.writeValueAsString(list);
|
|
} catch (JsonProcessingException e) {
|
|
throw new RuntimeException("Failed to serialize", e);
|
|
}
|
|
}
|
|
|
|
private List<String> fromJson(String json) {
|
|
if (json == null || json.isBlank()) return List.of();
|
|
try {
|
|
return mapper.readValue(json, new TypeReference<List<String>>() {});
|
|
} catch (JsonProcessingException e) {
|
|
return List.of();
|
|
}
|
|
}
|
|
}
|
|
|