File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package kr.itn.itnhub.review;
import kr.itn.itnhub.org.OrgNotFoundException;
import kr.itn.itnhub.org.OrganizationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
public class ReviewImportService {
private final ReviewParser parser;
private final ReviewItemMapper mapper;
private final OrganizationMapper orgMapper;
private final TransactionTemplate transactionTemplate;
public ReviewImportService(ReviewParser parser, ReviewItemMapper mapper, OrganizationMapper orgMapper,
PlatformTransactionManager transactionManager) {
this.parser = parser;
this.mapper = mapper;
this.orgMapper = orgMapper;
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
/**
* 엑셀 파싱은 DB와 무관하므로 트랜잭션 밖에서 수행한다(SeedService와 동일한 이유).
*/
public ReviewImportReport importFile(Long orgId, InputStream xlsx) {
if (orgMapper.findById(orgId) == null) {
throw new OrgNotFoundException("기관을 찾을 수 없습니다: " + orgId);
}
List<ReviewRow> rows = parser.parse(xlsx);
return transactionTemplate.execute(status -> importRows(orgId, rows));
}
private ReviewImportReport importRows(Long orgId, List<ReviewRow> rows) {
// 이미 DB에 있는 순번 + 이번 파일에서 먼저 처리된 순번을 모두 "이미 존재함"으로 취급한다
// (SeedService.seedRows와 동일한 관례 - 같은 순번이 파일에 중복돼 있어도 두 번째는 갱신으로 집계).
Set<Integer> seen = new HashSet<>(mapper.findSeqsByOrg(orgId));
int created = 0;
int updated = 0;
for (ReviewRow row : rows) {
if (seen.add(row.seq())) {
created++;
} else {
updated++;
}
mapper.upsertFromFile(toReviewItem(orgId, row));
}
return new ReviewImportReport(created, updated, rows.size());
}
private ReviewItem toReviewItem(Long orgId, ReviewRow row) {
ReviewItem item = new ReviewItem();
item.setOrgId(orgId);
item.setSeq(row.seq());
item.setSiteName(row.siteName());
item.setCategory(row.category());
item.setBoardPath(row.boardPath());
item.setBoardName(row.boardName());
item.setPostTitle(row.postTitle());
item.setUrl(row.url());
item.setPostRegistered(row.postRegistered());
item.setProducedDate(row.producedDate());
item.setPublishedDate(row.publishedDate());
item.setHasAttachment(row.hasAttachment());
item.setKoglAttached(row.koglAttached());
item.setKoglType(row.koglType());
item.setAiType(row.aiType());
item.setSurveyorNote(row.surveyorNote());
item.setOpenable(row.openable());
item.setReviewMajor(row.reviewMajor());
item.setReviewMinor(row.reviewMinor());
item.setReviewResult(row.reviewResult());
item.setJudgedKoglType(row.judgedKoglType());
item.setJudgedAiType(row.judgedAiType());
item.setOpinion(row.opinion());
item.setLawyerNote(row.lawyerNote());
item.setNeedsProcessing(row.needsProcessing());
return item;
}
}