|
|
|
|
@ -8,6 +8,8 @@ import go.kr.project.carInspectionPenalty.registration.config.CarFfnlgTxtParseCo
|
|
|
|
|
import go.kr.project.carInspectionPenalty.registration.mapper.CarFfnlgTrgtMapper;
|
|
|
|
|
import go.kr.project.carInspectionPenalty.registration.model.CarFfnlgTrgtVO;
|
|
|
|
|
import go.kr.project.carInspectionPenalty.registration.service.CarFfnlgTrgtService;
|
|
|
|
|
import go.kr.project.system.user.mapper.UserMapper;
|
|
|
|
|
import go.kr.project.system.user.model.SystemUserVO;
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
@ -37,6 +39,7 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
private final CarFfnlgTrgtMapper mapper;
|
|
|
|
|
private final CarFfnlgTxtParseConfig parseConfig;
|
|
|
|
|
private final VehicleInfoService vehicleInfoService;
|
|
|
|
|
private final UserMapper userMapper;
|
|
|
|
|
|
|
|
|
|
// 날짜 형식 (YYYYMMDD)
|
|
|
|
|
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
|
|
@ -902,6 +905,7 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
* @return 비교 결과
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional
|
|
|
|
|
public Map<String, Object> compareWithApi(List<Map<String, String>> targetList) {
|
|
|
|
|
log.info("========== API 호출 및 비교 시작 ==========");
|
|
|
|
|
log.info("선택된 데이터 건수: {}", targetList != null ? targetList.size() : 0);
|
|
|
|
|
@ -913,11 +917,15 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
List<Map<String, Object>> compareResults = new ArrayList<>();
|
|
|
|
|
int successCount = 0;
|
|
|
|
|
int failCount = 0;
|
|
|
|
|
int productUseCount = 0; // 상품용 건수
|
|
|
|
|
int transferCount = 0; // 이첩 건수
|
|
|
|
|
int normalCount = 0; // 정상 처리 건수
|
|
|
|
|
|
|
|
|
|
for (Map<String, String> target : targetList) {
|
|
|
|
|
String carFfnlgTrgtId = target.get("carFfnlgTrgtId");
|
|
|
|
|
String vhclno = target.get("vhclno");
|
|
|
|
|
String inspYmd = target.get("inspYmd");
|
|
|
|
|
String rgtr = target.get("rgtr"); // 등록자 (사용자 ID)
|
|
|
|
|
|
|
|
|
|
log.info("처리 중 - 차량번호: {}, 검사일자: {}", vhclno, inspYmd);
|
|
|
|
|
|
|
|
|
|
@ -955,13 +963,31 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. 데이터 비교
|
|
|
|
|
Map<String, Object> comparisonDetail = compareData(existingData, apiResponse);
|
|
|
|
|
// 3. 비교 로직 실행 (상품용 → 이첩 순서로 체크)
|
|
|
|
|
String processedStatus = processComparison(existingData, apiResponse, rgtr);
|
|
|
|
|
|
|
|
|
|
compareResult.put("success", true);
|
|
|
|
|
compareResult.put("message", "비교 완료");
|
|
|
|
|
compareResult.put("comparisonDetail", comparisonDetail);
|
|
|
|
|
successCount++;
|
|
|
|
|
if ("02".equals(processedStatus)) {
|
|
|
|
|
// 상품용으로 처리됨
|
|
|
|
|
productUseCount++;
|
|
|
|
|
compareResult.put("success", true);
|
|
|
|
|
compareResult.put("message", "상품용으로 처리되었습니다.");
|
|
|
|
|
compareResult.put("processStatus", "상품용");
|
|
|
|
|
successCount++;
|
|
|
|
|
} else if ("03".equals(processedStatus)) {
|
|
|
|
|
// 이첩으로 처리됨
|
|
|
|
|
transferCount++;
|
|
|
|
|
compareResult.put("success", true);
|
|
|
|
|
compareResult.put("message", "이첩으로 처리되었습니다.");
|
|
|
|
|
compareResult.put("processStatus", "이첩");
|
|
|
|
|
successCount++;
|
|
|
|
|
} else {
|
|
|
|
|
// 정상 처리 (비교 로직에 해당 안됨)
|
|
|
|
|
normalCount++;
|
|
|
|
|
compareResult.put("success", true);
|
|
|
|
|
compareResult.put("message", "정상 처리되었습니다.");
|
|
|
|
|
compareResult.put("processStatus", "정상");
|
|
|
|
|
successCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("데이터 비교 중 오류 발생 - 차량번호: {}", vhclno, e);
|
|
|
|
|
@ -978,21 +1004,127 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
resultData.put("totalCount", targetList.size());
|
|
|
|
|
resultData.put("successCount", successCount);
|
|
|
|
|
resultData.put("failCount", failCount);
|
|
|
|
|
resultData.put("productUseCount", productUseCount);
|
|
|
|
|
resultData.put("transferCount", transferCount);
|
|
|
|
|
resultData.put("normalCount", normalCount);
|
|
|
|
|
|
|
|
|
|
log.info("========== API 호출 및 비교 완료 ==========");
|
|
|
|
|
log.info("성공: {}건, 실패: {}건", successCount, failCount);
|
|
|
|
|
log.info("성공: {}건, 실패: {}건, 상품용: {}건, 이첩: {}건, 정상: {}건",
|
|
|
|
|
successCount, failCount, productUseCount, transferCount, normalCount);
|
|
|
|
|
|
|
|
|
|
return resultData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 비교 로직을 수행하고 업무 처리 상태를 업데이트
|
|
|
|
|
*
|
|
|
|
|
* 비교 순서:
|
|
|
|
|
* 1. 상품용 체크 (대표소유자성명에서 "상품용" 문자열 찾기)
|
|
|
|
|
* 2. 이첩 체크 (사용본거지법정동코드 앞 4자리 != 사용자 ORG_CD 앞 4자리)
|
|
|
|
|
* 3. 1개 로직이라도 걸리면 해당 상태로 업데이트하고 종료
|
|
|
|
|
*
|
|
|
|
|
* @param existingData 기존 과태료 대상 데이터
|
|
|
|
|
* @param apiResponse API 응답 데이터
|
|
|
|
|
* @param rgtr 등록자 (사용자 ID)
|
|
|
|
|
* @return 처리 상태 코드 (02=상품용, 03=이첩, null=해당 없음)
|
|
|
|
|
*/
|
|
|
|
|
private String processComparison(CarFfnlgTrgtVO existingData, VehicleApiResponseVO apiResponse, String rgtr) {
|
|
|
|
|
// API 응답 데이터 유효성 검사
|
|
|
|
|
if (apiResponse.getBasicInfo() == null ||
|
|
|
|
|
apiResponse.getBasicInfo().getRecord() == null ||
|
|
|
|
|
apiResponse.getBasicInfo().getRecord().isEmpty()) {
|
|
|
|
|
log.warn("API 응답 데이터가 없습니다. 차량번호: {}", existingData.getVhclno());
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
go.kr.project.api.model.response.BasicResponse.Record basicInfo = apiResponse.getBasicInfo().getRecord().get(0);
|
|
|
|
|
String vhclno = existingData.getVhclno();
|
|
|
|
|
|
|
|
|
|
// ========== 1. 상품용 체크 ==========
|
|
|
|
|
String mberNm = basicInfo.getMberNm(); // 대표소유자성명
|
|
|
|
|
if (mberNm != null && mberNm.contains("상품용")) {
|
|
|
|
|
log.info("[상품용 감지] 차량번호: {}, 소유자명: {}", vhclno, mberNm);
|
|
|
|
|
|
|
|
|
|
// 업무 처리 상태 업데이트
|
|
|
|
|
existingData.setTaskPrcsSttsCd("02"); // 02=상품용
|
|
|
|
|
existingData.setTaskPrcsYmd(LocalDate.now().format(DATE_FORMATTER));
|
|
|
|
|
existingData.setCarBscMttrInqFlnm(mberNm); // 자동차 기본 사항 조회 성명 저장
|
|
|
|
|
existingData.setCarBscMttrInqSggCd(null); // 이첩 필드는 null
|
|
|
|
|
existingData.setCarBscMttrInqSggNm(null);
|
|
|
|
|
|
|
|
|
|
int updateResult = mapper.update(existingData);
|
|
|
|
|
if (updateResult > 0) {
|
|
|
|
|
log.info("[상품용 처리 완료] 차량번호: {}", vhclno);
|
|
|
|
|
return "02";
|
|
|
|
|
} else {
|
|
|
|
|
log.error("[상품용 업데이트 실패] 차량번호: {}", vhclno);
|
|
|
|
|
throw new RuntimeException("상품용 업데이트 실패: " + vhclno);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ========== 2. 이첩 체크 ==========
|
|
|
|
|
String useStrnghldLegaldongCode = basicInfo.getUseStrnghldLegaldongCode(); // 사용본거지법정동코드
|
|
|
|
|
if (useStrnghldLegaldongCode != null && useStrnghldLegaldongCode.length() >= 4) {
|
|
|
|
|
// 사용자 정보 조회
|
|
|
|
|
SystemUserVO userInfo = userMapper.selectUser(rgtr);
|
|
|
|
|
if (userInfo == null || userInfo.getOrgCd() == null) {
|
|
|
|
|
log.warn("[이첩 체크 스킵] 사용자 정보 또는 조직코드가 없습니다. 사용자ID: {}", rgtr);
|
|
|
|
|
} else {
|
|
|
|
|
String userOrgCd = userInfo.getOrgCd();
|
|
|
|
|
|
|
|
|
|
// 법정동코드 앞 4자리와 사용자 조직코드 앞 4자리 비교
|
|
|
|
|
String legalDong4 = useStrnghldLegaldongCode.substring(0, 4);
|
|
|
|
|
String userOrg4 = userOrgCd.length() >= 4 ? userOrgCd.substring(0, 4) : userOrgCd;
|
|
|
|
|
|
|
|
|
|
if (!legalDong4.equals(userOrg4)) {
|
|
|
|
|
log.info("[이첩 감지] 차량번호: {}, 법정동코드: {}, 사용자조직코드: {}",
|
|
|
|
|
vhclno, legalDong4, userOrg4);
|
|
|
|
|
|
|
|
|
|
// 시군구 코드 (법정동코드 앞 5자리)
|
|
|
|
|
String sggCd = useStrnghldLegaldongCode.length() >= 5
|
|
|
|
|
? useStrnghldLegaldongCode.substring(0, 5)
|
|
|
|
|
: useStrnghldLegaldongCode;
|
|
|
|
|
|
|
|
|
|
// 시군구명 조회
|
|
|
|
|
String sggNm = mapper.selectSggNmBySggCd(sggCd);
|
|
|
|
|
if (sggNm == null || sggNm.isEmpty()) {
|
|
|
|
|
log.warn("[이첩 경고] 시군구명 조회 실패. 시군구코드: {}", sggCd);
|
|
|
|
|
sggNm = ""; // 시군구명이 없어도 이첩 처리는 진행
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 업무 처리 상태 업데이트
|
|
|
|
|
existingData.setTaskPrcsSttsCd("03"); // 03=이첩
|
|
|
|
|
existingData.setTaskPrcsYmd(LocalDate.now().format(DATE_FORMATTER));
|
|
|
|
|
existingData.setCarBscMttrInqFlnm(null); // 상품용 필드는 null
|
|
|
|
|
existingData.setCarBscMttrInqSggCd(sggCd); // 시군구 코드 저장
|
|
|
|
|
existingData.setCarBscMttrInqSggNm(sggNm); // 시군구명 저장
|
|
|
|
|
|
|
|
|
|
int updateResult = mapper.update(existingData);
|
|
|
|
|
if (updateResult > 0) {
|
|
|
|
|
log.info("[이첩 처리 완료] 차량번호: {}, 시군구: {}({})", vhclno, sggNm, sggCd);
|
|
|
|
|
return "03";
|
|
|
|
|
} else {
|
|
|
|
|
log.error("[이첩 업데이트 실패] 차량번호: {}", vhclno);
|
|
|
|
|
throw new RuntimeException("이첩 업데이트 실패: " + vhclno);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 비교 로직에 해당되지 않음
|
|
|
|
|
log.info("[정상 처리] 차량번호: {} - 상품용, 이첩에 해당하지 않음", vhclno);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 기존 데이터와 API 응답 데이터를 비교하는 로직
|
|
|
|
|
* TODO: 실제 비교 로직은 요구사항에 맞게 수정 필요
|
|
|
|
|
* @deprecated processComparison으로 대체됨
|
|
|
|
|
*
|
|
|
|
|
* @param existingData 기존 과태료 대상 데이터
|
|
|
|
|
* @param apiResponse API 응답 데이터
|
|
|
|
|
* @return 비교 결과 상세
|
|
|
|
|
*/
|
|
|
|
|
@Deprecated
|
|
|
|
|
private Map<String, Object> compareData(CarFfnlgTrgtVO existingData, VehicleApiResponseVO apiResponse) {
|
|
|
|
|
Map<String, Object> comparison = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
@ -1027,9 +1159,6 @@ public class CarFfnlgTrgtServiceImpl implements CarFfnlgTrgtService {
|
|
|
|
|
String apiVhclno = apiResponse.getLedgerInfo().getVhrno();
|
|
|
|
|
ledgerComparison.put("차량번호_일치여부", Objects.equals(existingVhclno, apiVhclno) ? "일치" : "불일치");
|
|
|
|
|
|
|
|
|
|
// TODO: 추가적인 등록원부 필드 비교 로직 작성
|
|
|
|
|
// 예: 차대번호, 등록일자 등
|
|
|
|
|
|
|
|
|
|
comparison.put("등록원부_비교", ledgerComparison);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|