From 89f6d58f9831e3a61274c888f927b2ba1f49ab93 Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Tue, 18 Nov 2025 15:38:44 +0300 Subject: [PATCH] =?UTF-8?q?-=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=91=D0=94:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8F,=20=D1=84=D0=BB=D0=B0=D0=B3=D0=B8=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=83=D1=8E=20=D1=82=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D1=86=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nbch/credit_tracker/config/AppConfig.java | 20 +++ .../config/task/PipelineStarterConfig.java | 8 - .../entities/app/FlagDetail.java | 21 +++ ...FlagsMapper.java => IndicFlagsMapper.java} | 2 +- .../mapper/signal/FlagDetailMapper.java | 9 ++ .../mapper/signal/PhoneFidMapMapper.java | 2 +- .../credit_tracker/model/SubjectProfile.java | 2 +- .../service/indic/FlagsService.java | 6 +- .../service/indic/FlagsService2.java | 37 ++++- .../service/indic/PhoneService2.java | 31 +++- .../service/task/impl/FlagsEnricher.java | 139 ------------------ .../service/task/impl/FlagsEnricherV2.java | 72 ++++----- .../service/task/impl/SaveSubjectHandler.java | 22 ++- .../mybatis/mapper/indic/FlagsMapper.xml | 2 +- .../mapper/signal/FlagDetailMapper.xml | 21 +++ .../mapper/signal/PhoneFidMapMapper.xml | 58 ++++++-- .../service/FlagsServiceTest.java | 4 +- 17 files changed, 241 insertions(+), 215 deletions(-) create mode 100644 src/main/java/ru/nbch/credit_tracker/config/AppConfig.java create mode 100644 src/main/java/ru/nbch/credit_tracker/entities/app/FlagDetail.java rename src/main/java/ru/nbch/credit_tracker/mapper/indic/{FlagsMapper.java => IndicFlagsMapper.java} (96%) create mode 100644 src/main/java/ru/nbch/credit_tracker/mapper/signal/FlagDetailMapper.java delete mode 100644 src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricher.java create mode 100644 src/main/resources/mybatis/mapper/signal/FlagDetailMapper.xml diff --git a/src/main/java/ru/nbch/credit_tracker/config/AppConfig.java b/src/main/java/ru/nbch/credit_tracker/config/AppConfig.java new file mode 100644 index 0000000..76778c4 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/config/AppConfig.java @@ -0,0 +1,20 @@ +package ru.nbch.credit_tracker.config; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AppConfig { + + @Bean + public ObjectMapper entityToJsonMapper() { + return new ObjectMapper() + .registerModule(new JavaTimeModule()) + .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/config/task/PipelineStarterConfig.java b/src/main/java/ru/nbch/credit_tracker/config/task/PipelineStarterConfig.java index c8d727e..9bd49ca 100644 --- a/src/main/java/ru/nbch/credit_tracker/config/task/PipelineStarterConfig.java +++ b/src/main/java/ru/nbch/credit_tracker/config/task/PipelineStarterConfig.java @@ -5,12 +5,9 @@ import java.util.function.Supplier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; -import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; import ru.nbch.credit_tracker.model.impl.PartFilePayload; import ru.nbch.credit_tracker.model.impl.SignalXmlFilePayload; import ru.nbch.credit_tracker.model.impl.SubjectPayload; -import ru.nbch.credit_tracker.service.indic.FlagsService2; -import ru.nbch.credit_tracker.service.task.impl.FlagsEnricher; import ru.nbch.credit_tracker.service.task.impl.KickPipeLineImpl; import ru.nbch.credit_tracker.service.task.impl.XmlMergeCoordinator; import ru.nbch.credit_tracker.service.task.setup.IPipeLineStarter; @@ -28,9 +25,4 @@ public class PipelineStarterConfig { public Supplier> pipelineTerminatorFactory(CreditTrackerSettings creditTrackerSettings) { return () -> new XmlMergeCoordinator(creditTrackerSettings); } - - @Bean - public Supplier flagEnricherFactory(FlagsService2 flagsService, PhoneFidMapMapper mapper) { - return () -> new FlagsEnricher(flagsService, mapper); - } } diff --git a/src/main/java/ru/nbch/credit_tracker/entities/app/FlagDetail.java b/src/main/java/ru/nbch/credit_tracker/entities/app/FlagDetail.java new file mode 100644 index 0000000..9c61b94 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/entities/app/FlagDetail.java @@ -0,0 +1,21 @@ +package ru.nbch.credit_tracker.entities.app; + +import java.time.LocalDateTime; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class FlagDetail { + private Long id; + private Long mapId; + private Long packageId; + private String subjectId; + private String phone; + private Integer fid; + private Integer flagDebt5000; + private Integer flag90days; + private LocalDateTime calculatedAt; +} diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/indic/IndicFlagsMapper.java similarity index 96% rename from src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java rename to src/main/java/ru/nbch/credit_tracker/mapper/indic/IndicFlagsMapper.java index bd7a5fc..166d055 100644 --- a/src/main/java/ru/nbch/credit_tracker/mapper/indic/FlagsMapper.java +++ b/src/main/java/ru/nbch/credit_tracker/mapper/indic/IndicFlagsMapper.java @@ -8,7 +8,7 @@ import ru.nbch.credit_tracker.entities.indic.PaymentsFlag; import ru.nbch.credit_tracker.service.indic.FlagsService; @Mapper -public interface FlagsMapper { +public interface IndicFlagsMapper { List findRuPastDuarearData(@Param("fids") List fids); List findRuPaymtData(@Param("fids") List fids, @Param("reportedDate") LocalDate reportedDate); diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/signal/FlagDetailMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/signal/FlagDetailMapper.java new file mode 100644 index 0000000..8ff1adc --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/mapper/signal/FlagDetailMapper.java @@ -0,0 +1,9 @@ +package ru.nbch.credit_tracker.mapper.signal; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface FlagDetailMapper { + void registerCalcFlags(@Param("json") String json); +} diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java index 6449955..f23ceb5 100644 --- a/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java +++ b/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java @@ -13,7 +13,7 @@ public interface PhoneFidMapMapper { void registerSubjects(@Param("subjects") List subjects, @Param("packageId") Long packageId); void register(@Param("phoneFidMap") List phoneFidMap); - void registerJson(@Param("json") String json); + List registerJson(@Param("json") String json); void registerWithId(@Param("phoneFidMap") List phoneFidMap); List findFullPhoneFidMap(@Param("packageId") Long packageId, @Param("offset") int offset, @Param("limit") int limit); diff --git a/src/main/java/ru/nbch/credit_tracker/model/SubjectProfile.java b/src/main/java/ru/nbch/credit_tracker/model/SubjectProfile.java index d284669..8f41a51 100644 --- a/src/main/java/ru/nbch/credit_tracker/model/SubjectProfile.java +++ b/src/main/java/ru/nbch/credit_tracker/model/SubjectProfile.java @@ -9,9 +9,9 @@ import lombok.Setter; @Builder public class SubjectProfile { private String identifier; + private Long mapId; private String phone; private Integer fid; private NameData nameData; private IdData idData; - } diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java index a8e8420..c5c3b9e 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Service; -import ru.nbch.credit_tracker.mapper.indic.FlagsMapper; +import ru.nbch.credit_tracker.mapper.indic.IndicFlagsMapper; import java.math.BigDecimal; import java.math.BigInteger; @@ -24,7 +24,7 @@ import ru.nbch.credit_tracker.model.SubjectProfile; public class FlagsService { private static final Logger log = LoggerFactory.getLogger(FlagsService.class); - private final FlagsMapper mapper; + private final IndicFlagsMapper mapper; private static final String SELECT_RU_PASDUEARREAR_DATA = "SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE, DAYS_PAST_DUE " + @@ -42,7 +42,7 @@ public class FlagsService { private final NamedParameterJdbcTemplate jdbcTemplate; - public FlagsService(FlagsMapper mapper, + public FlagsService(IndicFlagsMapper mapper, @Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) { this.mapper = mapper; this.jdbcTemplate = jdbcTemplate; diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService2.java b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService2.java index b31367a..ccd1171 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService2.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/FlagsService2.java @@ -1,21 +1,32 @@ package ru.nbch.credit_tracker.service.indic; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.time.LocalDate; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.app.FlagDetail; import ru.nbch.credit_tracker.entities.indic.PaymentsFlag; -import ru.nbch.credit_tracker.mapper.indic.FlagsMapper; +import ru.nbch.credit_tracker.mapper.indic.IndicFlagsMapper; +import ru.nbch.credit_tracker.mapper.signal.FlagDetailMapper; @Slf4j @Service public class FlagsService2 { - private final FlagsMapper flagsMapper; + private final IndicFlagsMapper flagsMapper; + private final FlagDetailMapper flagDetailMapper; + private final ObjectMapper entityToJsonMapper; - public FlagsService2(FlagsMapper flagsMapper) { + public FlagsService2(IndicFlagsMapper flagsMapper, + FlagDetailMapper flagDetailMapper, + ObjectMapper entityToJsonMapper) { this.flagsMapper = flagsMapper; + this.flagDetailMapper = flagDetailMapper; + this.entityToJsonMapper = entityToJsonMapper; } public Map findFlagsDebt5000(List fids) { @@ -33,5 +44,25 @@ public class FlagsService2 { .collect(Collectors.toMap(PaymentsFlag::getFid, PaymentsFlag::getFlag)); } + public void registerCalculationFlags(List flagDetails) { + try { + //fixme, временное решение + String jsonFlagDetail = entityToJsonMapper.writeValueAsString(flagDetails.stream() + .map(flagDetail -> new HashMap() {{ + put("subject_id", flagDetail.getSubjectId()); + put("fid", flagDetail.getFid()); + put("phone", flagDetail.getPhone()); + put("map_id", flagDetail.getMapId()); + put("package_id", flagDetail.getPackageId()); + put("flag_debt5000", flagDetail.getFlagDebt5000()); + put("flag_90_12", flagDetail.getFlag90days()); + put("calculated_at", flagDetail.getCalculatedAt()); + }}).toList()); + flagDetailMapper.registerCalcFlags(jsonFlagDetail); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java index 43414d2..530bffc 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java @@ -1,6 +1,9 @@ package ru.nbch.credit_tracker.service.indic; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BinaryOperator; @@ -8,7 +11,9 @@ import java.util.function.Function; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.app.PhoneFidMap; import ru.nbch.credit_tracker.entities.indic.Name; +import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; import ru.nbch.credit_tracker.model.SubjectProfile; import ru.nbch.credit_tracker.repository.PhoneRepository; import ru.nbch.credit_tracker.utils.CTUtil; @@ -18,16 +23,23 @@ import ru.nbch.credit_tracker.utils.CTUtil; public class PhoneService2 { private final PhoneRepository phoneRepository; + private final PhoneFidMapMapper phoneFidMapMapper; + private final ObjectMapper entityToJsonMapper; private final Comparator byDateThenIdNullSafe = Comparator.comparing(Name::getFileSinceDate, Comparator.nullsFirst(Comparator.naturalOrder())) .thenComparing(Name::getFid); - public PhoneService2(PhoneRepository phoneRepository) { + public PhoneService2(PhoneRepository phoneRepository, + PhoneFidMapMapper phoneFidMapMapper, + ObjectMapper entityToJsonMapper) { this.phoneRepository = phoneRepository; + this.phoneFidMapMapper = phoneFidMapMapper; + this.entityToJsonMapper = entityToJsonMapper; } /** * Поиск данных по таблицам PHONE_NORM и NAME по списку номеров телефонов + * * @param subjects * @return - отображение NAME к номеру телефону, отфильтрованному по логике * FID с максимальным значением FILE_SINCE_DT. Если FILE_SINCE_DT оказался одинаковый, берется максимальный FID @@ -46,4 +58,21 @@ public class PhoneService2 { BinaryOperator.maxBy(byDateThenIdNullSafe) )); } + + public List registerSubjects(List subjects) { + try { + //fixme, временное решение + String json = entityToJsonMapper.writeValueAsString(subjects.stream() + .map(phoneFidMap -> new HashMap() {{ + put("subject_id", phoneFidMap.getSubjectId()); + put("fid", phoneFidMap.getFid()); + put("phone", phoneFidMap.getPhone()); + put("package_id", phoneFidMap.getPackageId()); + put("calculated_at", phoneFidMap.getCalculatedAt()); + }}).toList()); + return phoneFidMapMapper.registerJson(json); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricher.java b/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricher.java deleted file mode 100644 index 19e6bcf..0000000 --- a/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricher.java +++ /dev/null @@ -1,139 +0,0 @@ -package ru.nbch.credit_tracker.service.task.impl; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.exception.ExceptionUtils; -import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; -import ru.nbch.credit_tracker.model.SubjectProfile; -import ru.nbch.credit_tracker.model.impl.SubjectPayload; -import ru.nbch.credit_tracker.service.indic.FlagsService2; - -@Slf4j -public class FlagsEnricher implements Runnable { - - private final FlagsService2 flagsService; - private final PhoneFidMapMapper phoneFidMapMapper; - private BlockingQueue in; - private final CompletableFuture done = new CompletableFuture<>(); - private final ExecutorService ioPool; - private final ObjectMapper mapper = new ObjectMapper() - .registerModule(new JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - - public FlagsEnricher(FlagsService2 flagsService, - PhoneFidMapMapper phoneFidMapMapper) { - this.flagsService = flagsService; - this.phoneFidMapMapper = phoneFidMapMapper; - this.ioPool = new ThreadPoolExecutor(10, - 10, - 0L, TimeUnit.MINUTES, - new LinkedBlockingQueue<>(), - r -> { - Thread t = new Thread(r); - t.setName("queue-handler-%s-%d".formatted(this.getClass().getSimpleName(), t.threadId())); - return t; - } - ); - } - - @Override - public void run() { - List> inFlight = new ArrayList<>(); - while (!Thread.currentThread().isInterrupted()) { - try { - SubjectPayload subjectPayload = in.poll(5, TimeUnit.SECONDS); - if (subjectPayload == null) { - continue; - } - if (subjectPayload.isPoison()) { - log.debug("Got poison"); - for (Future f : inFlight) { - f.get(); - } - done.complete(null); - return; - } - inFlight.add(ioPool.submit(() -> process(subjectPayload))); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } catch (Exception e) { - log.error("Error: {}", ExceptionUtils.getStackTrace(e)); - } - } - } - - public void process(SubjectPayload subjectPayload) { - List subjects = subjectPayload.getSubjects(); - log.debug("FlagsEnricher handle by packageId: {}, size: {}", subjectPayload.getPackageId(), subjects.size()); - - List fids = subjects.stream() - .map(SubjectProfile::getFid) - .filter(Objects::nonNull) - .toList(); - LocalDate yearAgo = LocalDate.now().minusYears(1); - - Map flagsDebt5000 = flagsService.findFlagsDebt5000(fids); - Map flag90ByPastDueArrear = flagsService.findFlag90ByPastDueArrear(fids, yearAgo); - Map flag90ByRuPaymt = flagsService.findFlag90ByRuPaymt(fids, yearAgo); - - String json; - try { - json = mapper.writeValueAsString(subjects.stream().map(subject -> { - Integer debt5000 = null; - Integer flagDays90 = null; - LocalDateTime calculatedAt = null; - - if (subject.getFid() != null) { - debt5000 = flagsDebt5000.getOrDefault(subject.getFid(), 0); - int pastDue90 = flag90ByPastDueArrear.getOrDefault(subject.getFid(), 0); - int paymt90 = flag90ByRuPaymt.getOrDefault(subject.getFid(), 0); - flagDays90 = Math.max(pastDue90, paymt90); - calculatedAt = LocalDateTime.now(); - } - - Integer finalDebt500 = debt5000; - Integer finalFlagDays9 = flagDays90; - LocalDateTime finalCalculatedAt = calculatedAt; - return new HashMap() {{ - put("subject_id", subject.getIdentifier()); - put("fid", subject.getFid()); - put("phone", subject.getPhone()); - put("package_id", subjectPayload.getPackageId()); - put("flag_debt5000", finalDebt500); - put("flag_90_12", finalFlagDays9); - put("calculated_at", finalCalculatedAt); - }}; - }).toList()); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - phoneFidMapMapper.registerJson(json); - } - - public void setPollingQueue(BlockingQueue queue) { - this.in = queue; - } - - public CompletableFuture doneFuture() { - return done; - } -} diff --git a/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricherV2.java b/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricherV2.java index 8bfb0f9..521ad15 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricherV2.java +++ b/src/main/java/ru/nbch/credit_tracker/service/task/impl/FlagsEnricherV2.java @@ -1,9 +1,11 @@ package ru.nbch.credit_tracker.service.task.impl; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -12,12 +14,9 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.app.FlagDetail; import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; import ru.nbch.credit_tracker.model.SubjectProfile; import ru.nbch.credit_tracker.model.impl.SubjectPayload; @@ -28,7 +27,6 @@ import ru.nbch.credit_tracker.service.indic.FlagsService2; public class FlagsEnricherV2 implements Consumer { private final FlagsService2 flagsService; - private final PhoneFidMapMapper phoneFidMapMapper; private final ExecutorService ioPool; private final ObjectMapper mapper = new ObjectMapper() .registerModule(new JavaTimeModule()) @@ -38,7 +36,6 @@ public class FlagsEnricherV2 implements Consumer { public FlagsEnricherV2(FlagsService2 flagsService, PhoneFidMapMapper phoneFidMapMapper) { this.flagsService = flagsService; - this.phoneFidMapMapper = phoneFidMapMapper; this.ioPool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MINUTES, @@ -66,46 +63,41 @@ public class FlagsEnricherV2 implements Consumer { Map flag90ByPastDueArrear = flagsService.findFlag90ByPastDueArrear(fids, yearAgo); Map flag90ByRuPaymt = flagsService.findFlag90ByRuPaymt(fids, yearAgo); - String json; - try { - json = mapper.writeValueAsString(subjects.stream().map(subject -> { - Integer debt5000 = null; - Integer flagDays90 = null; - LocalDateTime calculatedAt = null; + List flagDetails = subjects.stream().map(subject -> { + Integer debt5000 = null; + Integer flagDays90 = null; + LocalDateTime calculatedAt = null; - if (subject.getFid() != null) { - debt5000 = flagsDebt5000.getOrDefault(subject.getFid(), 0); - int pastDue90 = flag90ByPastDueArrear.getOrDefault(subject.getFid(), 0); - int paymt90 = flag90ByRuPaymt.getOrDefault(subject.getFid(), 0); - flagDays90 = Math.max(pastDue90, paymt90); - calculatedAt = LocalDateTime.now(); - } + if (subject.getFid() != null) { + debt5000 = flagsDebt5000.getOrDefault(subject.getFid(), 0); + int pastDue90 = flag90ByPastDueArrear.getOrDefault(subject.getFid(), 0); + int paymt90 = flag90ByRuPaymt.getOrDefault(subject.getFid(), 0); + flagDays90 = Math.max(pastDue90, paymt90); + calculatedAt = LocalDateTime.now(); + } - Integer finalDebt500 = debt5000; - Integer finalFlagDays9 = flagDays90; - LocalDateTime finalCalculatedAt = calculatedAt; - return new HashMap() {{ - put("subject_id", subject.getIdentifier()); - put("fid", subject.getFid()); - put("phone", subject.getPhone()); - put("package_id", subjectPayload.getPackageId()); - put("flag_debt5000", finalDebt500); - put("flag_90_12", finalFlagDays9); - put("calculated_at", finalCalculatedAt); - }}; - }).toList()); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - phoneFidMapMapper.registerJson(json); + Integer finalDebt500 = debt5000; + Integer finalFlagDays9 = flagDays90; + LocalDateTime finalCalculatedAt = calculatedAt; + + return FlagDetail.builder() + .mapId(subject.getMapId()) + .subjectId(subject.getIdentifier()) + .packageId(subjectPayload.getPackageId()) + .fid(subject.getFid()) + .phone(subject.getPhone()) + .flagDebt5000(finalDebt500) + .flag90days(finalFlagDays9) + .calculatedAt(finalCalculatedAt) + .build(); + }).toList(); + flagsService.registerCalculationFlags(flagDetails); } @Override public void accept(SubjectPayload subjectPayload) { ThreadPoolExecutor casted = (ThreadPoolExecutor) ioPool; log.info("submitting payload. active tasks number: {}; queue size: {}", casted.getActiveCount(), casted.getQueue().size()); - this.ioPool.submit(() -> { - process(subjectPayload); - }); + this.ioPool.submit(() -> process(subjectPayload)); } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/task/impl/SaveSubjectHandler.java b/src/main/java/ru/nbch/credit_tracker/service/task/impl/SaveSubjectHandler.java index 5bc45ed..b8bae2d 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/task/impl/SaveSubjectHandler.java +++ b/src/main/java/ru/nbch/credit_tracker/service/task/impl/SaveSubjectHandler.java @@ -1,9 +1,11 @@ package ru.nbch.credit_tracker.service.task.impl; +import java.time.LocalDateTime; import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.app.PhoneFidMap; import ru.nbch.credit_tracker.entities.indic.Name; import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; import ru.nbch.credit_tracker.model.NameData; @@ -36,9 +38,9 @@ public class SaveSubjectHandler implements Handler nameByPhone = phoneService2.findNameByNumber(subjects); - //todo сделать один проход для установки FID для вставки в PHONE_FID_MAP и одновременного заполнения инфо из Name для дальнейшей обработки - subjects.forEach(subject -> { + List subjectForSave = subjects.stream().map(subject -> { Name name = nameByPhone.get(CTUtil.normalizePhoneNumber(subject.getPhone())); if (name != null) { NameData nameData = NameData.builder() @@ -52,8 +54,20 @@ public class SaveSubjectHandler implements Handler ids = phoneService2.registerSubjects(subjectForSave); + for (int i = 0; i < subjects.size(); i++) { + subjects.get(i).setMapId(ids.get(i)); + } return new SubjectPayload(taskPayload.getPackageId(), subjects); } } diff --git a/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml b/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml index 3e1a923..5de94f2 100644 --- a/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml +++ b/src/main/resources/mybatis/mapper/indic/FlagsMapper.xml @@ -3,7 +3,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + diff --git a/src/main/resources/mybatis/mapper/signal/FlagDetailMapper.xml b/src/main/resources/mybatis/mapper/signal/FlagDetailMapper.xml new file mode 100644 index 0000000..2a4013c --- /dev/null +++ b/src/main/resources/mybatis/mapper/signal/FlagDetailMapper.xml @@ -0,0 +1,21 @@ + + + + + + + INSERT INTO signals_flags + (map_id, subject_id, fid, phone, flag_debt5000, flag_90_12, calculated_at) + SELECT map_id, subject_id, fid, phone, flag_debt5000, flag_90_12, calculated_at + FROM json_to_recordset(#{json}::json) AS t( + map_id bigint, + subject_id varchar(255), + fid int, + phone text, + flag_debt5000 smallint, + flag_90_12 smallint, + calculated_at timestamp) + + \ No newline at end of file diff --git a/src/main/resources/mybatis/mapper/signal/PhoneFidMapMapper.xml b/src/main/resources/mybatis/mapper/signal/PhoneFidMapMapper.xml index 4f763e9..1e55556 100644 --- a/src/main/resources/mybatis/mapper/signal/PhoneFidMapMapper.xml +++ b/src/main/resources/mybatis/mapper/signal/PhoneFidMapMapper.xml @@ -33,19 +33,55 @@ - + + + + + + + + + + + + + + + INSERT INTO signals_phone_fid_map (subject_id, phone, package_id) diff --git a/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java b/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java index 944e8c1..abb79fd 100644 --- a/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java +++ b/src/test/java/ru/nbch/credit_tracker/service/FlagsServiceTest.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import ru.nbch.credit_tracker.mapper.indic.FlagsMapper; +import ru.nbch.credit_tracker.mapper.indic.IndicFlagsMapper; import ru.nbch.credit_tracker.service.indic.FlagsService; import java.math.BigDecimal; @@ -26,7 +26,7 @@ public class FlagsServiceTest { private static final LocalDate INITIAL_DATE = LocalDate.parse("2025-09-25"); @Mock - FlagsMapper flagsMapper; + IndicFlagsMapper flagsMapper; @Test public void testfindFlags() {