feat : epost 1차 완료, 개발하면서 테스트를 못돌렸음. 사이드 이팩트 많을것으로 예상됨.

todo : 통합 우편서버 sftp작업
master
Kurt92 3 months ago
parent b840989ee0
commit 91b28e38cf

@ -29,7 +29,7 @@ start "" "C:\Program Files\Eclipse Adoptium\jdk-17.0.15.6-hotspot\bin\java.exe"
- 대신 로그를 볼려면 실행로그파일을 따로 지정해줘야 된다.
<br/>
![스크린샷 2025-09-09 오전 10.13.50.png](../../../../../var/folders/qj/hwm278q51bg1yghyw_bybl5h0000gn/T/TemporaryItems/NSIRD_screencaptureui_TNPAv2/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202025-09-09%20%EC%98%A4%EC%A0%84%2010.13.50.png)
- 수동실행을 위한 뷰페이지 localhost:8011로 접속하면됨.
- 로그보기를 누르면 실시간 로그도 볼수 있음.
- 프로그램 실행유무는 로컬호스트 8011을 접속 가능 여부로 판단하면됨.
@ -82,7 +82,7 @@ exit /b 0
- setinfo는 멀티 PK임. CODE_NAME, GROUP_CODE, DETAIL_CODE
[신문고]
- CODE_NANE(PK) : WORKER
- CODE_NAME(PK) : WORKER
- GROUP_CODE(PK) : INFO
- DETAIL_CODE(PK) : PROD
- INT_VALUE1 : 메인 시군구 코드
@ -95,7 +95,7 @@ exit /b 0
- STR_VALUE6 : 하위 모든 시군구 + 부서코드 제이슨 형태 ex) {"수정구":[41131, 3790009], "중원구":[41133, 3800009], "분당구": [41135, 3810070]}
[E-Post]
- CODE_NANE(PK) :
- CODE_NAME(PK) :
- GROUP_CODE(PK) :
- DETAIL_CODE(PK) :
- INT_VALUE1 :
@ -108,7 +108,7 @@ exit /b 0
- STR_VALUE6 :
- CODE_NANE(PK) :
- CODE_NAME(PK) :
- GROUP_CODE(PK) :
- DETAIL_CODE(PK) :
- INT_VALUE1 :

@ -0,0 +1,31 @@
package com.worker.domain.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Table(
name = "epost_rgst_nmbr",
indexes = {
@Index(name = "EPOST_RGST_NMBR_IDX1", columnList = "PCURSOR")
}
)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class EpostRgstNmbr {
@Id
@Column(name = "RGST_NMBR", columnDefinition = "char(13)", nullable = false)
private String rgstNmbr;
@Column(name = "RGST_NMBR_NEXT", columnDefinition = "char(13)")
private String rgstNmbrNext;
@Column(name = "PCURSOR", columnDefinition = "char(1)")
private String pcursor;
}

@ -3,6 +3,8 @@ package com.worker.domain.repo.cp;
import com.worker.domain.entity.EpostMakeResult;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface CpEPostMakeResultRepository extends JpaRepository<EpostMakeResult,Long> {
EpostMakeResult findByConkeyAndRgstNmbr();
Optional<EpostMakeResult> findByConKeyAndRgstNmbr(String conKey, String rgstNmbr);
}

@ -0,0 +1,10 @@
package com.worker.domain.repo.cp;
import com.worker.domain.entity.EpostRgstNmbr;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface CpEPostRgstNmbr extends JpaRepository<EpostRgstNmbr, Integer> {
EpostRgstNmbr findByPcursor(String cursor);
}

@ -3,5 +3,8 @@ package com.worker.domain.repo.ep;
import com.worker.domain.entity.EpostMakeResult;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface EpEPostMakeResultRepository extends JpaRepository<EpostMakeResult, Long> {
Optional<EpostMakeResult> findByConKeyAndRgstNmbr(String conKey, String rgstNmbr);
}

@ -0,0 +1,9 @@
package com.worker.domain.repo.ep;
import com.worker.domain.entity.EpostRgstNmbr;
import com.worker.domain.repo.cp.CpEPostRgstNmbr;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EpEPostRgstNmbr extends JpaRepository<EpostRgstNmbr, Integer> {
EpostRgstNmbr findByPcursor(String number);
}

@ -5,6 +5,7 @@ import jakarta.persistence.Column;
import lombok.*;
import java.util.List;
import java.util.Optional;
public class EPostDto {
@ -61,8 +62,14 @@ public class EPostDto {
@Builder
public static class Key {
private String conKey;
private String tgGb;
private String tgCode;
private String postProcStt;
private String regYmd;
private String tgUnitySndngMastrId;
private String tgPostYn;
}
@Getter
@Setter
@NoArgsConstructor
@ -70,37 +77,17 @@ public class EPostDto {
@Builder
public static class Target {
//cp_gojit
//epost_sender_result
private Long tgCode;
private String tgSggCode;
private String tgLawGb;
private String tgGb;
private String tgDlgb;
private String tgSrcSdate;
private String tgSrcEdate;
private String tgSdate;
private String tgEdate;
private String tgTitle;
private String tgDocno;
private String tgEtc;
private Integer tgTotcount;
private Long tgTotkeum;
private String tgIndt;
private Integer tgInuser;
private String tgConKey;
private String tgPostSeCd;
private String tgIsResend;
private String tgNoticeKey;
private String tgPostProcStt;
private String tgUnitySndngMastrId;
private String tgDelete;
private String tgPostYn;
private String tgElpostYn;
private String ConKey;
//epost_sender_reg
private String conKey;
private String regYmd;
//epost_sender_detail
private String rgstNmbr;
private String recevSeq; //mm_code
//tb_cntc_sndng_result
private String sndngResultSttus;
}
}

@ -1,8 +1,10 @@
package com.worker.scheduler.epost.repository;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.worker.domain.entity.CpGojiSendHist;
import com.worker.domain.entity.EpostRgstNmbr;
import com.worker.scheduler.epost.dto.EPostDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -18,6 +20,7 @@ import static com.worker.domain.entity.QCpGojit.cpGojit;
import static com.worker.domain.entity.QCpInstruct.cpInstruct;
import static com.worker.domain.entity.QCpInstructAnswer.cpInstructAnswer;
import static com.worker.domain.entity.QEpostDelivResult.epostDelivResult;
import static com.worker.domain.entity.QEpostRgstNmbr.epostRgstNmbr;
import static com.worker.domain.entity.QEpostSenderDetail.epostSenderDetail;
import static com.worker.domain.entity.QEpostSenderReg.epostSenderReg;
import static com.worker.domain.entity.QTbCntcSndngDetail.tbCntcSndngDetail;
@ -36,7 +39,12 @@ public class EPostQueryDslRepository {
Projections.fields(
EPostDto.SendTarget.Key.class,
cpGojit.tgCode,
epostSenderReg.conKey
cpGojit.tgGb,
epostSenderReg.conKey,
epostSenderReg.postProcStt,
epostSenderReg.regYmd,
Expressions.as(Expressions.nullExpression(String.class), "tgPostYn"),
Expressions.as(Expressions.nullExpression(String.class), "tgUnitySndngMastrId")
)
)
.from(epostSenderReg)
@ -49,6 +57,7 @@ public class EPostQueryDslRepository {
}
// 일반 발송
public List<EPostDto.SendTarget.Target> findSendTargets(JPAQueryFactory queryFactory, List<EPostDto.SendTarget.Key> keys) {
List<String> tgCode = keys.stream().map(EPostDto.SendTarget.Key::getTgCode).collect(Collectors.toList());
@ -58,7 +67,10 @@ public class EPostQueryDslRepository {
.select(
Projections.fields(
EPostDto.SendTarget.Target.class,
cpGojit.tgCode
epostSenderReg.tgCode,
epostSenderReg.conKey,
epostSenderDetail.rgstNmbr,
epostSenderDetail.recevSeq
)
)
.from(epostSenderReg)
@ -78,16 +90,23 @@ public class EPostQueryDslRepository {
return result;
}
// 전자고지를 쓰는 서버 발송
// 전자고지 테이블 조인함.
public List<EPostDto.SendTarget.Target> findSendEgojiTargets(JPAQueryFactory queryFactory, List<EPostDto.SendTarget.Key> keys) {
List<String> tgCode = keys.stream().map(EPostDto.SendTarget.Key::getTgCode).collect(Collectors.toList());
List<String> conKey = keys.stream().map(EPostDto.SendTarget.Key::getConKey).collect(Collectors.toList());
List<String> unitySndngMastrId = keys.stream().map(EPostDto.SendTarget.Key::getTgUnitySndngMastrId).collect(Collectors.toList());
List<EPostDto.SendTarget.Target> result = queryFactory
.select(
Projections.fields(
EPostDto.SendTarget.Target.class,
cpGojit.tgCode
epostSenderReg.tgCode,
epostSenderReg.conKey,
epostSenderDetail.rgstNmbr,
epostSenderDetail.recevSeq,
tbCntcSndngResult.sndngResultSttus
)
)
.from(epostSenderReg)
@ -97,15 +116,13 @@ public class EPostQueryDslRepository {
cpInstruct.itSggcode.eq(cpInstructAnswer.id.iaSggcode),
cpInstruct.itCause.eq(cpInstructAnswer.id.iaCode)
)
.leftJoin(tbCntcSndngDetail).on(
epostSenderDetail.recevSeq.eq(tbCntcSndngDetail.mainCode)
)
.leftJoin(tbCntcSndngDetail).on(epostSenderDetail.recevSeq.eq(tbCntcSndngDetail.mainCode))
.leftJoin(tbCntcSndngResult).on(tbCntcSndngDetail.unitySndngDetailId.eq(tbCntcSndngResult.unitySndngDetailId))
.where(
epostSenderReg.postProcStt.eq("01"),
epostSenderReg.tgCode.in(tgCode),
epostSenderReg.conKey.in(conKey),
tbCntcSndngDetail.unitySndngMastrId.eq(""),
tbCntcSndngDetail.unitySndngMastrId.in(unitySndngMastrId),
tbCntcSndngResult.sndngResultSttus.ne("READ")
.and(tbCntcSndngResult.sndngResultSttus.isNull()
)
@ -237,7 +254,7 @@ public class EPostQueryDslRepository {
.fetch();
// updateRceptResult(queryFactory, dtos, results);
updateRecvResult(queryFactory, dtos, results);
return results;
}
@ -314,6 +331,30 @@ public class EPostQueryDslRepository {
}
public void updateSenderRegPostStt(JPAQueryFactory queryFactory, List<EPostDto.SendTarget.Target> cpSendTargets) {
List<String> conKeys = cpSendTargets.stream()
.map(post -> post.getConKey())
.collect(Collectors.toUnmodifiableList());
queryFactory.update(epostSenderReg)
.set(epostSenderReg.postProcStt, "03")
.where(epostSenderReg.conKey.in(conKeys))
.execute();
}
public void updateGojitPostYn(JPAQueryFactory queryFactory, List<EPostDto.SendTarget.Target> cpSendEgojiTargets) {
List<String> conKeys = cpSendEgojiTargets.stream()
.map(post -> post.getConKey())
.collect(Collectors.toUnmodifiableList());
queryFactory.update(cpGojit)
.set(cpGojit.tgPostYn, "Y")
.where(cpGojit.tgConKey.in(conKeys))
.execute();
}
public Long findEpostDelivResultMaxKey(JPAQueryFactory queryFactory, String conKey) {
return queryFactory
.select(epostDelivResult.seqKey.max())
@ -330,4 +371,29 @@ public class EPostQueryDslRepository {
.fetchOne();
}
public void updateOldPostToCancel(JPAQueryFactory queryFactory, List<EPostDto.SendTarget.Key> oldPosts) {
List<String> conKeys = oldPosts.stream()
.map(post -> post.getConKey())
.collect(Collectors.toUnmodifiableList());
queryFactory.update(epostSenderReg)
.set(epostSenderReg.postProcStt, "02")
.where(epostSenderReg.conKey.in(conKeys))
.execute();
}
public void updateTrgstNmbr(JPAQueryFactory queryFactory, EpostRgstNmbr trgstNmbr){
queryFactory.update(epostRgstNmbr)
.set(epostRgstNmbr.pcursor, "0")
.where(epostRgstNmbr.rgstNmbr.eq(trgstNmbr.getRgstNmbr()))
.execute();
queryFactory.update(epostRgstNmbr)
.set(epostRgstNmbr.pcursor, "1")
.where(epostRgstNmbr.rgstNmbr.eq(trgstNmbr.getRgstNmbrNext()))
.execute();
}
}

@ -28,15 +28,13 @@ public class EPostScheduler {
private final FileReader fileReader;
/**
* Send
* text
* */
// @Scheduled(fixedRate = 10 * 60 * 1000L) // 10분
public void ePostSendScheduler() {
/**
*
* , text
* */
// esb경로 info
EPostDto.SetInfo setInfo = epostSetinfoService.findSetInfo();
@ -44,24 +42,13 @@ public class EPostScheduler {
ePostService.findEPostSendTarget(setInfo);
//발송대상 찾기
//findEPostSendTarget()
//대상 text만들기
}
/**
* Recv
*
* */
// @Scheduled(fixedRate = 10 * 60 * 1000) // 10분
public void ePostRcvScheduler() {
@ -86,5 +73,14 @@ public class EPostScheduler {
}
/**
*
* sftp .
* */
// @Scheduled(fixedRate = 10 * 60 * 1000) // 10분
public void getFileFromIntergrationServer() {
}
}

@ -8,6 +8,8 @@ import com.worker.domain.repo.cp.*;
import com.worker.domain.repo.ep.*;
import com.worker.scheduler.epost.dto.EPostDto;
import com.worker.scheduler.epost.repository.EPostQueryDslRepository;
import com.worker.util.common.CommonUtils;
import com.worker.util.zipFileMaker.ZipMaker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -26,6 +28,8 @@ import java.util.stream.Collectors;
public class EPostService {
private final Environment env;
private final CommonUtils utils;
private final ZipMaker zipMaker;
private final ObjectMapper objectMapper;
private final CpSetinfoRepository cpSetinfoRepository;
@ -44,6 +48,8 @@ public class EPostService {
private final EpEPostSenderDetailRepository epEPostSenderDetailRepository;
private final CpEPostSenderRegRepository cpEPostSenderRegRepository;
private final EpEPostSenderRegRepository epEPostSenderRegRepository;
private final CpEPostRgstNmbr cpEPostRgstNmbr;
private final EpEPostRgstNmbr epEPostRgstNmbr;
private final EPostQueryDslRepository ePostQueryDslRepository;
@ -66,56 +72,120 @@ public class EPostService {
List<EPostDto.SendTarget.Key> cpSendTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Key> epSendTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Key> cpSendEpostTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Key> epSendEpostTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Key> cpSendEgojiTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Key> epSendEgojiTargetKeys = new ArrayList<>();
List<EPostDto.SendTarget.Target> cpSendTargets = new ArrayList<>();
List<EPostDto.SendTarget.Target> epSendTargets = new ArrayList<>();
List<EPostDto.SendTarget.Target> cpSendEgojiTargets = new ArrayList<>();
List<EPostDto.SendTarget.Target> epSendEgojiTargets = new ArrayList<>();
// 타겟의 키,code 조회
//cGojit
// getTgPostYn 이 전자고지를 안쓰는 경우 컬럼자체가 존재하지 않음.
// 해서 queryDsl에서는 익스프래셔으로 널처리
//Gojit
if(setInfo.getCpEPostInfo() != null) cpSendTargetKeys = ePostQueryDslRepository.findSendTargetKeys(cpQueryFactory);
if(setInfo.getEpEPostInfo() != null) epSendTargetKeys = ePostQueryDslRepository.findSendTargetKeys(epQueryFactory);
// 전자고지/일반 대상 분리
// getTgPostYn 널처리
// 스트림에서는 오브젝트 이퀄로 널처리 (null 이면 걸러짐)
cpSendEgojiTargetKeys = cpSendTargetKeys.stream()
.filter(target -> Objects.equals(target.getTgPostYn(), "E"))
.toList();
epSendEgojiTargetKeys = epSendTargetKeys.stream()
.filter(target -> Objects.equals(target.getTgPostYn(), "E"))
.toList();
cpSendEpostTargetKeys = cpSendTargetKeys.stream()
.filter(target -> target.getTgPostYn() == null || target.getTgPostYn().equals("N"))
.toList();
epSendEpostTargetKeys = epSendTargetKeys.stream()
.filter(target -> target.getTgPostYn() == null || target.getTgPostYn().equals("N"))
.toList();
// 조회한 키로 cpSendTargets 의 상세내용 조회
// qryFor
// 일반
if(!cpSendEpostTargetKeys.isEmpty()) cpSendTargets = ePostQueryDslRepository.findSendTargets(cpQueryFactory, cpSendTargetKeys);
if(!epSendEpostTargetKeys.isEmpty()) epSendTargets = ePostQueryDslRepository.findSendTargets(epQueryFactory, epSendTargetKeys);
if(setInfo.getCpIsEns() || setInfo.getEpIsEns()) {
// 전자고지 대상 조회
// qryEgoji
if(setInfo.getCpIsEns()) cpSendTargets = ePostQueryDslRepository.findSendEgojiTargets(cpQueryFactory, cpSendTargetKeys);
if(setInfo.getEpIsEns()) epSendTargets = ePostQueryDslRepository.findSendEgojiTargets(epQueryFactory, epSendTargetKeys);
} else {
// 조회한 키로 cpSendTargets 의 상세내용 조회
// qryFor
cpSendTargets = ePostQueryDslRepository.findSendTargets(cpQueryFactory, cpSendTargetKeys);
epSendTargets = ePostQueryDslRepository.findSendTargets(epQueryFactory, epSendTargetKeys);
if (setInfo.getCpIsEns())
cpSendEgojiTargets = ePostQueryDslRepository.findSendEgojiTargets(cpQueryFactory, cpSendEgojiTargetKeys);
if (setInfo.getEpIsEns())
epSendEgojiTargets = ePostQueryDslRepository.findSendEgojiTargets(epQueryFactory, epSendEgojiTargetKeys);
}
// REG_YMD 오늘기준 30일 이전 자료들 취소(POST_PROC_STT = '02') 로 변경
try {
cancelOldPost(cpSendTargetKeys, epSendTargetKeys);
} catch (Exception e) {
log.error("30일 이전 자료들 취소 실패: cpKeys={}, epKeys={}", cpSendTargetKeys == null ? 0 : cpSendTargetKeys.size(), epSendTargetKeys == null ? 0 : epSendTargetKeys.size(), e);
throw e;
}
//notice(안내문구 인거같음)
//goit notifce 조인
//goit notice 조인
// notice 안씀. 관련 로직 폐기해도 됨.
// 사전통보 or 계도 대상에서 mmcode만 추출 (prt_gubun = '0'사전통보 || prt_gubun = 'A' 계도)
// 사전 & 계도는 사진 같이 나감.
final List<EPostDto.SendTarget.Target> cpTargets = Optional.ofNullable(cpSendTargets).orElseGet(List::of);
List<String> targetCpMmCodes = cpSendTargetKeys.stream()
.filter(o -> "0".equals(o.getTgGb()) || "A".equals(o.getTgGb()))
.flatMap(o -> cpTargets.stream()
.filter(t -> Objects.equals(o.getConKey(), t.getConKey()))
.map(EPostDto.SendTarget.Target::getRecevSeq))
.filter(Objects::nonNull)
.distinct()
.toList();
final List<EPostDto.SendTarget.Target> epTargets = Optional.ofNullable(epSendTargets).orElseGet(List::of);
List<String> targetEpMmCodes = epSendTargetKeys.stream()
.filter(o -> "0".equals(o.getTgGb()) || "A".equals(o.getTgGb()))
.flatMap(o -> epTargets.stream()
.filter(t -> Objects.equals(o.getConKey(), t.getConKey()))
.map(EPostDto.SendTarget.Target::getRecevSeq))
.filter(Objects::nonNull)
.distinct()
.toList();
// mmcode로 이미지 파일 찾아서 zip생성
try {
zipMaker.generateZipFile(targetCpMmCodes, targetEpMmCodes, setInfo);
} catch (Exception e) {
log.error("ZIP 파일 생성 실패 : " + e.getMessage());
}
// SendTargets 돌면서 전자고지인지 체크후 후처리
// 이거 필요 없을듯. 전자고지인지 체크후 그냥 빼버리면됨.
// 아래 스트림에서 전자고지 아닌것만 으로 스트림 돌리면됨.
// SendTargets 돌면서 전자고지인지 체크
// 거기서 대기상태("E") 인 얘들의 등기번호를 업데이트
// cpSendEgojiTargetKeys 등기번호 업데이트 하면 될듯
egojiNonReadTargetsUpdateTrgstNmbr(cpSendEgojiTargets, epSendEgojiTargets);
// SendTargets 돌면서 전자고지 아닌거 후처리 하는데
// 이거 그냥 리스트를 나눠서 따로따로 진행하는게 더 깔끔함
// steam 으로 전송대상(전자고지 아닌것) 만 추출하셈
// 전송대상은 tg_post_yn 이 'E' 이거나 'Y' 인것만임.
// E는 대기상태로 전자고지를 안읽었으면 추후 예약발송 한다는거임.
// POST_SEND_STATE 업데이트 to "1"
updateSendState(cpSendTargets, epSendTargets, cpSendEgojiTargets, epSendEgojiTargets);
// 전송대상 등기번호 조회
// 전자고지 아니면 textMakcer
// zipMaker
//qryRegSet stt = 03 으로 업데이트
//qryRegSet POST_PROC_STT = 03, TG_POST_YN = "Y" 으로 업데이트
if(!cpSendTargets.isEmpty()) ePostQueryDslRepository.updateSenderRegPostStt(cpQueryFactory, cpSendTargets);
if(!epSendEgojiTargets.isEmpty()) ePostQueryDslRepository.updateGojitPostYn(epQueryFactory, cpSendEgojiTargets);
if(!cpSendTargets.isEmpty()) ePostQueryDslRepository.updateSenderRegPostStt(cpQueryFactory, epSendTargets);
if(!epSendEgojiTargets.isEmpty()) ePostQueryDslRepository.updateGojitPostYn(epQueryFactory, epSendEgojiTargets);
// 서울시는 통합 우편서버를 사용중임.
// 거기다가 ftp 로 텍스트 쏴줘야함.
// 그리고 파일 읽는것도 마찬가지
}
@ -182,11 +252,7 @@ public class EPostService {
if(epPrts != null && !epPrts.isEmpty()) {
insertPrtResults(epPrts, parseResult, "ep");
}
// if (delivs != null && !delivs.isEmpty()) insertDelivResults(delivs);
// if (prts != null && !prts.isEmpty()) insertPrtResults(prts);
// if (recvs != null && !recvs.isEmpty()) insertRecvResults(recvs);
// recv는 조회후 바로 업데이트해서 따로 구조변경이 없음, 때문에 queryDsl안에서 조회후 바로 업데이트 함.
}
@ -227,9 +293,9 @@ public class EPostService {
}
//EPOST_MAKE_RESULT 의 콘키와 등기번호로 조회한 결과가 없으면
EpostMakeResult epostMakeResult = null;
if(dbKind.equals("cp")) epostMakeResult = cpEPostMakeResultRepository.findByConkeyAndRgstNmbr();
else epostMakeResult = cpEPostMakeResultRepository.findByConkeyAndRgstNmbr();
Optional<EpostMakeResult> epostMakeResult = null;
if(dbKind.equals("cp")) epostMakeResult = cpEPostMakeResultRepository.findByConKeyAndRgstNmbr(fileResult.getConKey(), fileResult.getRestNmbr());
else epostMakeResult = epEPostMakeResultRepository.findByConKeyAndRgstNmbr(fileResult.getConKey(), fileResult.getRestNmbr());
//EPOST_MAKE_RESULT 인서트
if(epostMakeResult == null) {
@ -246,10 +312,6 @@ public class EPostService {
}
}
});
}
@ -366,31 +428,10 @@ public class EPostService {
epGojiSendHistRepository.saveAll(cpGojiSendHists);
epEpostDelivResultRepository.saveAll(epostDelivResults);
}
}
private void insertReceiveResults(List<EPostDto.Recv> recvs) {
//고지 업데이트
//reg 업데이트
}
private Set<String> parseDeptCode(EPostDto.SetInfo setInfo, String kind) {
String json = null;
if(kind.equals("cp") && setInfo.getCpSetinfo() != null)
@ -440,12 +481,132 @@ public class EPostService {
return maxKey;
}
private String takeRgstNmbr() {
String regNo = null;
private void cancelOldPost(List<EPostDto.SendTarget.Key> cpSendTargetKeys, List<EPostDto.SendTarget.Key> epSendTargetKeys) {
String before30DaysFromNow = LocalDateTime.now().minusDays(30).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
List<EPostDto.SendTarget.Key> oldCpPosts = cpSendTargetKeys.stream()
.filter(post -> post.getRegYmd().compareTo(before30DaysFromNow) < 0)
.toList();
List<EPostDto.SendTarget.Key> oldEpPosts = epSendTargetKeys.stream()
.filter(post -> post.getRegYmd().compareTo(before30DaysFromNow) < 0)
.toList();
if(!oldCpPosts.isEmpty()) ePostQueryDslRepository.updateOldPostToCancel(cpQueryFactory, oldCpPosts);
if(!oldEpPosts.isEmpty()) ePostQueryDslRepository.updateOldPostToCancel(epQueryFactory, oldEpPosts);
return regNo;
}
private void egojiNonReadTargetsUpdateTrgstNmbr(List<EPostDto.SendTarget.Target> cpSendEgojiTargets, List<EPostDto.SendTarget.Target> epSendEgojiTargets) {
List<EpostSenderDetail> cpEpostSenderDetails = new ArrayList<>();
List<EpostSenderDetail> epEpostSenderDetails = new ArrayList<>();
List<CpGojiPrt> cpGojiPrts = new ArrayList<>();
List<CpGojiPrt> epGojiPrts = new ArrayList<>();
cpSendEgojiTargets.forEach(sendTarget -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.rgstNmbr(generateTrgstNmbr("cp"))
.conKey(sendTarget.getConKey())
.recevSeq(sendTarget.getRecevSeq()) // mmcode
.build();
cpEpostSenderDetails.add(epostSenderDetail);
CpGojiPrt cpGojiPrt = CpGojiPrt.builder()
.gpRegistNo(generateTrgstNmbr("cp"))
.gpConKey(sendTarget.getConKey())
.gpMmcode(sendTarget.getRecevSeq()) // mmcode
.build();
cpGojiPrts.add(cpGojiPrt);
});
epSendEgojiTargets.forEach(sendTarget -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.rgstNmbr(generateTrgstNmbr("cp"))
.conKey(sendTarget.getConKey())
.recevSeq(sendTarget.getRecevSeq()) // mmcode
.build();
epEpostSenderDetails.add(epostSenderDetail);
CpGojiPrt cpGojiPrt = CpGojiPrt.builder()
.gpRegistNo(generateTrgstNmbr("cp"))
.gpConKey(sendTarget.getConKey())
.gpMmcode(sendTarget.getRecevSeq()) // mmcode
.build();
epGojiPrts.add(cpGojiPrt);
});
if(!cpEpostSenderDetails.isEmpty()) cpEPostSenderDetailRepository.saveAll(cpEpostSenderDetails);
if(!epEpostSenderDetails.isEmpty()) epEPostSenderDetailRepository.saveAll(epEpostSenderDetails);
if(!cpGojiPrts.isEmpty()) cpGojiPrtRepository.saveAll(cpGojiPrts);
if(!epGojiPrts.isEmpty()) epGojiPrtRepository.saveAll(epGojiPrts);
}
private void updateSendState(
List<EPostDto.SendTarget.Target> cpSendTargets, List<EPostDto.SendTarget.Target> epSendTargets,
List<EPostDto.SendTarget.Target> cpSendEpostTargets, List<EPostDto.SendTarget.Target> epSendEpostTargets) {
List<EpostSenderDetail> cpEpostSenderDetails = new ArrayList<>();
List<EpostSenderDetail> epEpostSenderDetails = new ArrayList<>();
// POST_SEND_STATE = '1'
cpSendTargets.forEach(target -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.postSendState("1")
.conKey(target.getConKey())
.recevSeq(target.getRecevSeq()) // mmcode
.build();
cpEpostSenderDetails.add(epostSenderDetail);
});
epSendTargets.forEach(target -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.postSendState("1")
.conKey(target.getConKey())
.recevSeq(target.getRecevSeq()) // mmcode
.build();
epEpostSenderDetails.add(epostSenderDetail);
});
cpSendEpostTargets.forEach(target -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.postSendState("1")
.conKey(target.getConKey())
.recevSeq(target.getRecevSeq()) // mmcode
.build();
cpEpostSenderDetails.add(epostSenderDetail);
});
epSendEpostTargets.forEach(target -> {
EpostSenderDetail epostSenderDetail = EpostSenderDetail.builder()
.postSendState("1")
.conKey(target.getConKey())
.recevSeq(target.getRecevSeq()) // mmcode
.build();
epEpostSenderDetails.add(epostSenderDetail);
});
if(!cpEpostSenderDetails.isEmpty()) cpEPostSenderDetailRepository.saveAll(cpEpostSenderDetails);
if(!epEpostSenderDetails.isEmpty()) epEPostSenderDetailRepository.saveAll(epEpostSenderDetails);
}
private String generateTrgstNmbr(String dbKind) {
// select * from EPOST_RGST_NMBR where pcursor= '1' ;
String regiNo = null;
EpostRgstNmbr cpTrgstNmbr = cpEPostRgstNmbr.findByPcursor("1");
EpostRgstNmbr epTrgstNmbr = epEPostRgstNmbr.findByPcursor("1");
if(dbKind.equals("cp")) {
regiNo = cpTrgstNmbr.getRgstNmbr();
ePostQueryDslRepository.updateTrgstNmbr(cpQueryFactory, cpTrgstNmbr);
}
if(dbKind.equals("ep")) {
regiNo = epTrgstNmbr.getRgstNmbr();
ePostQueryDslRepository.updateTrgstNmbr(epQueryFactory, epTrgstNmbr);
}
return regiNo;
}
}

@ -1,12 +1,16 @@
package com.worker.util.common;
import com.worker.util.common.commEnum.DateTimePatternEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@Component
@Slf4j
public class CommonUtils {
/**
@ -50,21 +54,15 @@ public class CommonUtils {
/**
*
* */
/**
*
* */
// 스캐쥴러 에러 체킹을 위한 펑셔널 인터페이스 로깅 매서드
public void runStep(String step, Runnable r) {
try {
r.run();
} catch (Exception e) {
log.error("[{}] 실패", step, e);
throw new RuntimeException(e);
}
}
}

@ -1,4 +1,99 @@
package com.worker.util.zipFileMaker;
import com.worker.scheduler.epost.dto.EPostDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Component
@Slf4j
public class ZipMaker {
private static final List<String> SUFFIXES = Arrays.asList("A", "B", "C", "D");
/**
* CP/EP .jpeg ZIP .
*/
public void generateZipFile(List<String> cpMmCodes, List<String> epMmCodes, EPostDto.SetInfo setInfo) throws IOException {
Objects.requireNonNull(setInfo, "setInfo is null");
String cpPath = setInfo.getCpSetinfo().getStrValue5();
String epPath = setInfo.getEpSetinfo().getStrValue5();
String cpZipPath = setInfo.getCpSetinfo().getStrValue4();
String epZipPath = setInfo.getCpSetinfo().getStrValue4();
// ZIP 저장 디렉토리 없으면 생성
File cpZipFile = new File(cpZipPath);
File epZipFile = new File(epZipPath);
try {
FileOutputStream fosCp = new FileOutputStream(cpZipFile);
FileOutputStream fosEp = new FileOutputStream(epZipFile);
ZipOutputStream zosCp = new ZipOutputStream(fosCp);
ZipOutputStream zosEp = new ZipOutputStream(fosEp);
// 1) CP
for (String code : safeList(cpMmCodes)) {
List<File> files = findExistingJpegs(cpPath, code);
addFilesToZip(zosCp, files, code + "/");
}
// 2) EP
for (String code : safeList(epMmCodes)) {
List<File> files = findExistingJpegs(epPath, code);
addFilesToZip(zosEp, files, code + "/");
}
} catch(Exception e) {
log.error("ZIP 객체 생성 실패 : " + e.getMessage());
}
}
/** baseDir/code + (A|B|C|D).jpeg 중 존재하는 파일만 수집 */
private List<File> findExistingJpegs(String baseDir, String code) {
List<File> found = new ArrayList<>();
if (isBlank(baseDir) || isBlank(code)) return found;
for (String sfx : SUFFIXES) {
String filename = code + sfx + ".jpeg";
File f = new File(baseDir, filename);
if (f.isFile()) {
found.add(f); // 존재하는 것만 담음 (A/B만 있으면 A,B만)
}
}
return found;
}
/** ZIP에 파일 추가 */
private void addFilesToZip(ZipOutputStream zos, List<File> files, String zipFolderPrefix) throws IOException {
for (File file : files) {
String entryName = zipFolderPrefix + file.getName();
zos.putNextEntry(new ZipEntry(entryName));
try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) != -1) {
zos.write(buf, 0, n);
}
}
zos.closeEntry();
}
}
private static <T> List<T> safeList(List<T> list) {
return list == null ? Collections.emptyList() : list;
}
private static boolean isBlank(String s) {
return s == null || s.trim().isEmpty();
}
}

Loading…
Cancel
Save