package com.talentcard.server.business.portal;
|
|
import java.sql.Date;
|
import java.time.LocalDate;
|
import java.time.format.DateTimeParseException;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
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 ChildInformationPortalService {
|
|
private final JdbcTemplate jdbc;
|
|
public ChildInformationPortalService(JdbcTemplate jdbc) {
|
this.jdbc = jdbc;
|
}
|
|
@Transactional(readOnly = true)
|
public List<Map<String, Object>> list(Long talentId) {
|
ensureTalent(talentId);
|
return query("""
|
select id, child_name, gender, birth_date, audit_status, reject_reason, created_at, submitted_at
|
from child_information where talent_id = ? and deleted = 0
|
order by created_at desc, id desc
|
""", talentId).stream().map(this::listView).toList();
|
}
|
|
@Transactional(readOnly = true)
|
public Map<String, Object> detail(Long childId, Long talentId) {
|
Map<String, Object> row = child(childId, talentId);
|
if (!"审核不通过".equals(text(row.get("auditStatus")))) {
|
throw new BusinessException(ErrorCode.CONFLICT, "当前子女资料不需要重新提交");
|
}
|
Map<String, Object> result = listView(row);
|
result.put("canResubmit", true);
|
return result;
|
}
|
|
@Transactional
|
public Map<String, Object> create(ChildInformationRequest request, String idempotencyKey) {
|
ensureTalent(request.talentId());
|
validate(request, idempotencyKey);
|
List<Map<String, Object>> duplicates = query("""
|
select id from child_information where talent_id = ? and idempotency_key = ? and deleted = 0
|
""", request.talentId(), idempotencyKey);
|
if (!duplicates.isEmpty()) return listView(child(((Number) duplicates.get(0).get("id")).longValue(), request.talentId()));
|
jdbc.update("""
|
insert into child_information(talent_id, child_name, gender, birth_date, proof_file_ids, audit_status, idempotency_key, submitted_at)
|
values (?, ?, ?, ?, ?, '待审核', ?, now())
|
""", request.talentId(), clean(request.name()), clean(request.gender()), Date.valueOf(birthDate(request.birthDate())), proofIds(request.proofFileIds()), idempotencyKey);
|
Long childId = jdbc.queryForObject("select id from child_information where talent_id = ? and idempotency_key = ?", Long.class, request.talentId(), idempotencyKey);
|
if (childId == null) throw new BusinessException(ErrorCode.INTERNAL_ERROR, "子女资料提交失败");
|
return listView(child(childId, request.talentId()));
|
}
|
|
@Transactional
|
public Map<String, Object> resubmit(Long childId, ChildInformationRequest request, String idempotencyKey) {
|
ensureTalent(request.talentId());
|
validate(request, idempotencyKey);
|
Map<String, Object> current = child(childId, request.talentId());
|
if (idempotencyKey.equals(text(current.get("idempotencyKey")))) return listView(current);
|
if (!"审核不通过".equals(text(current.get("auditStatus")))) {
|
throw new BusinessException(ErrorCode.CONFLICT, "当前子女资料不允许重复提交");
|
}
|
jdbc.update("""
|
update child_information
|
set child_name = ?, gender = ?, birth_date = ?, proof_file_ids = ?, audit_status = '待审核',
|
reject_reason = null, idempotency_key = ?, submitted_at = now(), updated_at = now()
|
where id = ? and talent_id = ? and deleted = 0
|
""", clean(request.name()), clean(request.gender()), Date.valueOf(birthDate(request.birthDate())), proofIds(request.proofFileIds()), idempotencyKey, childId, request.talentId());
|
return listView(child(childId, request.talentId()));
|
}
|
|
private Map<String, Object> child(Long childId, Long talentId) {
|
if (childId == null || childId <= 0) throw new BusinessException(ErrorCode.BAD_REQUEST, "子女资料信息不能为空");
|
List<Map<String, Object>> rows = query("""
|
select id, child_name, gender, birth_date, audit_status, reject_reason, idempotency_key, created_at, submitted_at
|
from child_information where id = ? and talent_id = ? and deleted = 0
|
""", childId, talentId);
|
if (rows.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND, "子女资料不存在或无权查看");
|
return rows.get(0);
|
}
|
|
private Map<String, Object> listView(Map<String, Object> row) {
|
Map<String, Object> result = new java.util.LinkedHashMap<>();
|
result.put("id", row.get("id"));
|
result.put("name", row.get("childName"));
|
result.put("gender", row.get("gender"));
|
result.put("birthDate", String.valueOf(row.get("birthDate")));
|
result.put("status", text(row.get("auditStatus")));
|
result.put("rejectReason", text(row.get("rejectReason")));
|
result.put("createdAt", row.get("createdAt"));
|
result.put("submittedAt", row.get("submittedAt"));
|
return result;
|
}
|
|
private void ensureTalent(Long talentId) {
|
if (talentId == null || talentId <= 0 || !Boolean.TRUE.equals(jdbc.queryForObject("select exists(select 1 from talent_user where id = ? and deleted = 0)", Boolean.class, talentId))) {
|
throw new BusinessException(ErrorCode.NOT_FOUND, "人才用户不存在");
|
}
|
}
|
|
private void validate(ChildInformationRequest request, String idempotencyKey) {
|
if (idempotencyKey == null || idempotencyKey.isBlank() || idempotencyKey.length() > 128) throw new BusinessException(ErrorCode.BAD_REQUEST, "提交凭证不能为空");
|
if (!List.of("男", "女").contains(clean(request.gender()))) throw new BusinessException(ErrorCode.BAD_REQUEST, "请选择有效的性别");
|
if (request.proofFileIds().size() > 3 || request.proofFileIds().stream().anyMatch(id -> id == null || id.isBlank() || id.length() > 255)) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "证明材料格式不正确");
|
}
|
birthDate(request.birthDate());
|
}
|
|
private LocalDate birthDate(String value) {
|
try {
|
LocalDate date = LocalDate.parse(clean(value));
|
if (date.isAfter(LocalDate.now())) throw new BusinessException(ErrorCode.BAD_REQUEST, "出生日期不能晚于今天");
|
return date;
|
} catch (DateTimeParseException error) {
|
throw new BusinessException(ErrorCode.BAD_REQUEST, "出生日期格式不正确");
|
}
|
}
|
|
private List<Map<String, Object>> query(String sql, Object... args) {
|
return DatabaseRows.normalize(jdbc.queryForList(sql, args));
|
}
|
|
private String proofIds(List<String> values) {
|
return values.stream().map(String::trim).collect(Collectors.joining(","));
|
}
|
|
private String clean(String value) {
|
return value == null ? "" : value.trim();
|
}
|
|
private String text(Object value) {
|
return value == null ? "" : String.valueOf(value);
|
}
|
}
|