package com.talentcard.server.business.portal;
|
|
import java.time.LocalDate;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import com.talentcard.server.business.BusinessIdGenerator;
|
import com.talentcard.server.business.DatabaseRows;
|
import com.talentcard.server.common.BusinessException;
|
import com.talentcard.server.common.ErrorCode;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
@Service
|
public class CardUpgradePortalService {
|
|
private static final List<String> CARD_LEVELS = List.of("菁英人才卡", "杰出人才卡", "卓越人才卡");
|
|
private final JdbcTemplate jdbcTemplate;
|
|
public CardUpgradePortalService(JdbcTemplate jdbcTemplate) {
|
this.jdbcTemplate = jdbcTemplate;
|
}
|
|
@Transactional(readOnly = true)
|
public Map<String, Object> current(Long talentId) {
|
Map<String, Object> card = currentCard(talentId);
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("currentCardLevel", card.get("cardLevel"));
|
result.put("targetCardLevels", targetLevels(String.valueOf(card.get("cardLevel"))));
|
latestApplication(talentId).ifPresent(application -> result.put("application", application));
|
return result;
|
}
|
|
@Transactional
|
public Map<String, Object> submit(CardUpgradeRequest request, String idempotencyKey) {
|
if (idempotencyKey == null || idempotencyKey.isBlank() || idempotencyKey.length() > 128) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "提交凭证不能为空");
|
}
|
List<Map<String, Object>> duplicates = query("select id from upgrade_application where idempotency_key = ?", idempotencyKey);
|
if (!duplicates.isEmpty()) {
|
return application(((Number) duplicates.get(0).get("id")).longValue());
|
}
|
|
Map<String, Object> card = currentCard(request.talentId());
|
List<String> targetLevels = targetLevels(String.valueOf(card.get("cardLevel")));
|
if (!targetLevels.contains(request.targetCardLevel())) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "目标人才卡等级不正确");
|
}
|
validateHonors(request.honors());
|
|
String applicationNo = BusinessIdGenerator.next("UP");
|
jdbcTemplate.update("""
|
insert into upgrade_application(application_no, talent_id, talent_name, talent_mobile, talent_card_no,
|
current_level, target_level, apply_reason, apply_time, status, idempotency_key)
|
select ?, t.id, t.name, t.mobile, ?, ?, ?, ?, now(), '待审核', ?
|
from talent_user t where t.id = ? and t.deleted = 0
|
""",
|
applicationNo,
|
card.get("cardNo"),
|
card.get("cardLevel"),
|
request.targetCardLevel(),
|
"通过人才端提交升级申请",
|
idempotencyKey,
|
request.talentId());
|
Long applicationId = jdbcTemplate.queryForObject("select id from upgrade_application where idempotency_key = ?", Long.class, idempotencyKey);
|
if (applicationId == null) {
|
throw new BusinessException(ErrorCode.INTERNAL_ERROR, "升级申请创建失败");
|
}
|
for (int index = 0; index < request.honors().size(); index++) {
|
CardUpgradeRequest.Honor honor = request.honors().get(index);
|
jdbcTemplate.update("""
|
insert into upgrade_application_honor(application_id, honor_name, obtained_date, proof_file_id, sort_no)
|
values (?, ?, ?, ?, ?)
|
""", applicationId, honor.name().trim(), LocalDate.parse(honor.obtainedDate()), honor.proofFileIds().get(0), index + 1);
|
}
|
return application(applicationId);
|
}
|
|
private void validateHonors(List<CardUpgradeRequest.Honor> honors) {
|
for (CardUpgradeRequest.Honor honor : honors) {
|
try {
|
LocalDate obtainedDate = LocalDate.parse(honor.obtainedDate());
|
if (obtainedDate.isAfter(LocalDate.now())) throw new BusinessException(ErrorCode.BAD_REQUEST, "获得时间不能晚于今天");
|
} catch (java.time.format.DateTimeParseException exception) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "获得时间格式不正确");
|
}
|
for (String proofFileId : honor.proofFileIds()) {
|
if (proofFileId == null || !proofFileId.startsWith("/uploads/")) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "印证资料文件不正确");
|
}
|
}
|
}
|
}
|
|
private Map<String, Object> currentCard(Long talentId) {
|
if (talentId == null) throw new BusinessException(ErrorCode.BAD_REQUEST, "人才信息不能为空");
|
List<Map<String, Object>> cards = query("""
|
select id as card_id, card_no, card_level
|
from talent_card
|
where deleted = 0 and talent_id = ? and card_type = 'PERSONAL' and status = 1
|
order by id desc limit 1
|
""", talentId);
|
if (cards.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "未找到有效人才卡");
|
return cards.get(0);
|
}
|
|
private List<String> targetLevels(String currentLevel) {
|
int currentIndex = CARD_LEVELS.indexOf(currentLevel);
|
if (currentIndex < 0 || currentIndex == CARD_LEVELS.size() - 1) return List.of();
|
return CARD_LEVELS.subList(currentIndex + 1, CARD_LEVELS.size());
|
}
|
|
private java.util.Optional<Map<String, Object>> latestApplication(Long talentId) {
|
List<Map<String, Object>> applications = query("""
|
select id from upgrade_application
|
where talent_id = ? and deleted = 0
|
order by apply_time desc, id desc limit 1
|
""", talentId);
|
return applications.isEmpty() ? java.util.Optional.empty() : java.util.Optional.of(application(((Number) applications.get(0).get("id")).longValue()));
|
}
|
|
private Map<String, Object> application(Long applicationId) {
|
List<Map<String, Object>> applications = query("select * from upgrade_application where id = ? and deleted = 0", applicationId);
|
if (applications.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "升级申请不存在");
|
Map<String, Object> row = applications.get(0);
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("applicationId", String.valueOf(row.get("id")));
|
result.put("targetCardLevel", row.get("targetLevel"));
|
result.put("status", applicationStatus(String.valueOf(row.get("status"))));
|
result.put("rejectReason", row.get("auditRemark"));
|
result.put("honors", query("""
|
select honor_name as name, obtained_date, proof_file_id
|
from upgrade_application_honor where application_id = ? order by sort_no, id
|
""", applicationId).stream().map(honor -> Map.of(
|
"name", honor.get("name"),
|
"obtainedDate", String.valueOf(honor.get("obtainedDate")),
|
"proofFileIds", List.of(honor.get("proofFileId"))
|
)).toList());
|
return result;
|
}
|
|
private String applicationStatus(String status) {
|
return switch (status) {
|
case "已通过" -> "approved";
|
case "已驳回" -> "rejected";
|
case "草稿" -> "draft";
|
default -> "reviewing";
|
};
|
}
|
|
private List<Map<String, Object>> query(String sql, Object... args) {
|
return DatabaseRows.normalize(jdbcTemplate.queryForList(sql, args));
|
}
|
}
|