From d45e270c001268db9cf664e5998b9d1ad31635bd Mon Sep 17 00:00:00 2001 From: lulz1 Date: Thu, 4 Jul 2024 15:29:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BF=AE=E5=A4=8D=E7=BB=86=E8=8A=82?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/OrderApplicationService.java | 4 +- .../aggregates/approval/ApprovalLegAdd.java | 5 ++ .../ApprovalLegAddAndChangeBatch.java | 71 ++++++++++++++++--- .../approval/ApprovalLegChange.java | 5 ++ .../approval/ApprovalOrderChange.java | 5 ++ .../approval/ApprovalOrderExpense.java | 5 ++ .../approval/ApprovalOrderRefund.java | 5 ++ .../aggregates/approval/ApprovalProcess.java | 13 ++++ .../chint/domain/aggregates/order/Leg.java | 17 +++++ .../PermissionConfigRepositoryImpl.java | 15 ++-- .../CachePermissionConfigRepository.java | 16 ++++- .../infrastructure/util/DelayDispatch.java | 8 ++- 12 files changed, 148 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/chint/application/services/OrderApplicationService.java b/src/main/java/com/chint/application/services/OrderApplicationService.java index 9a8b9721..ac42f029 100644 --- a/src/main/java/com/chint/application/services/OrderApplicationService.java +++ b/src/main/java/com/chint/application/services/OrderApplicationService.java @@ -134,7 +134,7 @@ public class OrderApplicationService { .reloadStatus(); Leg oldLeg = leg.deepClone(); - + oldLeg.setRouteId(null); // 对 leg 进行更新 leg.update(legData); @@ -149,7 +149,7 @@ public class OrderApplicationService { //这里加入一个待审批事件, 变更加入旧行程数据, 用于回滚还原 leg.addEvent(LegApprovalEvent.prepare(oldLeg)); } - if (!routeOrder.getOrderStatus().equals(ORDER_STATUS_PREPARE) && !approveOrderNo.getSysCode().equals("ANFSSC")){ + if (!routeOrder.getOrderStatus().equals(ORDER_STATUS_PREPARE) && !approveOrderNo.getSysCode().equals("ANFSSC")) { sendLegChangeCommand(oldLeg, leg, routeOrder, addLegData.getLegData().getChangeReason(), diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAdd.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAdd.java index bb92be80..36bb561d 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAdd.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAdd.java @@ -19,6 +19,11 @@ public class ApprovalLegAdd extends ApprovalProcess { return this; } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + return null; + } + @Override public ApprovalProcess approveData(RouteOrder routeOrder, OrderDetail orderDetail) { return null; diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAddAndChangeBatch.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAddAndChangeBatch.java index aaef5daf..199a05b0 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAddAndChangeBatch.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegAddAndChangeBatch.java @@ -10,6 +10,7 @@ import org.springframework.data.util.Pair; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import static com.chint.domain.aggregates.approval.ApprovalType.LEG_ADD_CHANGE_BATCH; @@ -23,27 +24,79 @@ public class ApprovalLegAddAndChangeBatch extends ApprovalProcess { this.approvalType = LEG_ADD_CHANGE_BATCH; } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + ApprovalData approvalData = new ApprovalData(); + Map> partitionedLegs = partitionLegsByExtension( + routeOrder.getLegItems(), + LEG_APPROVAL_STATUS_SUBMIT, + approvalRecord.getApprovalRecordNo() + ); + List changeLegs = partitionedLegs.get(true); + List addLegs = partitionedLegs.get(false); + List> pairList = createLegPairs(changeLegs); + approvalData.setRouteOrder(routeOrder); + approvalData.setAddLegList(addLegs); + approvalData.setChangeLegList(pairList); + return approvalData; + } + @Override public ApprovalProcess approveData(RouteOrder routeOrder) { Map> legMap = routeOrder.getLegItems() .stream() .filter(it -> it.getLegApprovalStatus().equals(LEG_APPROVAL_STATUS_PREPARE)) - .collect(Collectors.partitioningBy(it -> it.getLastEvent().getExtension() == null - || it.getLastEvent().getExtension().isEmpty())); + .collect(Collectors.partitioningBy(this::isExtensionNullOrEmpty)); ApprovalData approvalData = new ApprovalData(); approvalData.setRouteOrder(routeOrder); approvalData.setAddLegList(legMap.get(true)); - List> pairList = legMap.get(false).stream() - .map(leg -> { - String extension = leg.getLastEvent().getExtension(); - Leg oldLeg = leg.deepClone().restoreFromLegString(extension); - return Pair.of(leg, oldLeg); - }).toList(); + List> pairList = createLegPairs(legMap.get(false)); approvalData.setChangeLegList(pairList); this.approvalData = approvalData; return this; } + private Map> partitionLegsByExtension(List legs, Integer approvalStatus, String approvalRecordNo) { + return legs.stream() + .peek(Leg::reloadStatus) + .filter(leg -> isLegApprovedAndMatchesRecord(leg, approvalStatus, approvalRecordNo)) + .collect(Collectors.partitioningBy(this::isExtensionNotNullOrEmpty)); + } + + private boolean isLegApprovedAndMatchesRecord(Leg leg, Integer approvalStatus, String approvalRecordNo) { + return leg.getLegApprovalStatus().equals(approvalStatus) && + leg.getLastApprovalSubmitEvent().isPresent() && + leg.getLastApprovalSubmitEvent().get().getExtension().equals(approvalRecordNo) && + leg.getLastApprovalPrepareEvent().isPresent(); + } + + private boolean isExtensionNotNullOrEmpty(Leg leg) { + Optional lastApprovalPrepareEvent = leg.getLastApprovalPrepareEvent(); + if(lastApprovalPrepareEvent.isEmpty()){ + return false; + } + String extension = lastApprovalPrepareEvent.get().getExtension(); + return extension != null && !extension.isEmpty(); + } + + private boolean isExtensionNullOrEmpty(Leg leg) { + String extension = leg.getLastEvent().getExtension(); + return extension == null || extension.isEmpty(); + } + + private List> createLegPairs(List legs) { + return legs.stream() + .filter(leg -> leg.getLastApprovalPrepareEvent().isPresent()) + .map(leg -> { + String extension = leg.getLastApprovalPrepareEvent().get().getExtension(); + Leg oldLeg = leg.deepClone().restoreFromLegString(extension); + return Pair.of(leg, oldLeg); + }) + .toList(); + } + + + @Override public boolean approve() { @@ -78,7 +131,7 @@ public class ApprovalLegAddAndChangeBatch extends ApprovalProcess { return false; } BaseEvent lastEvent = leg.getLastEvent(); - if(lastEvent == null){ + if (lastEvent == null) { return false; } return lastEvent.getEventType().equals(LEG_APPROVAL_STATUS_SUBMIT) && diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegChange.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegChange.java index 26ffd5a7..f75914a0 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegChange.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalLegChange.java @@ -14,6 +14,11 @@ public class ApprovalLegChange extends ApprovalProcess{ this.approvalType = LEG_CHANGE; } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + return null; + } + @Override public ApprovalProcess approveData(RouteOrder routeOrder) { return this; diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderChange.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderChange.java index 566093cc..692945d7 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderChange.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderChange.java @@ -13,6 +13,11 @@ public class ApprovalOrderChange extends ApprovalProcess{ this.approvalType = LEG_CHANGE; } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + return null; + } + @Override public ApprovalProcess approveData(RouteOrder routeOrder) { return this; diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderExpense.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderExpense.java index 4a4721be..4c0e0129 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderExpense.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderExpense.java @@ -28,6 +28,11 @@ public class ApprovalOrderExpense extends ApprovalProcess{ } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + return null; + } + @Override public ApprovalProcess doSubmitToBpm() { bpmPlatform.submitOrderExpenseApproval(approvalData); diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderRefund.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderRefund.java index 7ff8d3c9..f6f434f6 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderRefund.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalOrderRefund.java @@ -13,6 +13,11 @@ public class ApprovalOrderRefund extends ApprovalProcess { this.approvalType = ORDER_REFUND; } + @Override + protected ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + return null; + } + @Override public ApprovalProcess approveData(RouteOrder routeOrder) { return this; diff --git a/src/main/java/com/chint/domain/aggregates/approval/ApprovalProcess.java b/src/main/java/com/chint/domain/aggregates/approval/ApprovalProcess.java index 25dc933c..c686360b 100644 --- a/src/main/java/com/chint/domain/aggregates/approval/ApprovalProcess.java +++ b/src/main/java/com/chint/domain/aggregates/approval/ApprovalProcess.java @@ -34,6 +34,19 @@ public abstract class ApprovalProcess { return this; } + public ApprovalProcess approveData(RouteOrder routeOrder, ApprovalRecord approvalRecord) { + validateApprovalStatus(approvalRecord); + this.approvalData = recoverApproveData(routeOrder, approvalRecord); + return this; + } + + private void validateApprovalStatus(ApprovalRecord approvalRecord) { + if (!approvalRecord.getApprovalStatus().equals(ApprovalRecord.prepareApprovalStatus())) { + throw new CommandException("该审批单已经审批完毕,无法再次发起审批。"); + } + } + + protected abstract ApprovalData recoverApproveData(RouteOrder routeOrder, ApprovalRecord approvalRecord); public ApprovalProcess approveData(RouteOrder routeOrder, OrderDetail orderDetail) { ApprovalData approvalData = new ApprovalData(); diff --git a/src/main/java/com/chint/domain/aggregates/order/Leg.java b/src/main/java/com/chint/domain/aggregates/order/Leg.java index 767b332e..53541204 100644 --- a/src/main/java/com/chint/domain/aggregates/order/Leg.java +++ b/src/main/java/com/chint/domain/aggregates/order/Leg.java @@ -455,4 +455,21 @@ public class Leg implements Serializable, EventManageable { .filter(legEvent -> legEvent.getEventType().equals(LEG_EVENT_CHANGE)) .max(Comparator.comparing(LegEvent::getHappenTime)); } + + public Optional getLastApprovalSubmitEvent() { + return getLastApprovalEventByType(LEG_APPROVAL_STATUS_SUBMIT); + } + + public Optional getLastApprovalPrepareEvent() { + return getLastApprovalEventByType(LEG_APPROVAL_STATUS_PREPARE); + } + + private Optional getLastApprovalEventByType(Integer eventType) { + if (this.legApprovalEventList == null) { + return Optional.empty(); + } + return this.legApprovalEventList.stream() + .filter(legEvent -> legEvent.getEventType().equals(eventType)) + .max(Comparator.comparing(LegApprovalEvent::getHappenTime)); + } } \ No newline at end of file diff --git a/src/main/java/com/chint/infrastructure/repository/PermissionConfigRepositoryImpl.java b/src/main/java/com/chint/infrastructure/repository/PermissionConfigRepositoryImpl.java index 9136c025..36e36328 100644 --- a/src/main/java/com/chint/infrastructure/repository/PermissionConfigRepositoryImpl.java +++ b/src/main/java/com/chint/infrastructure/repository/PermissionConfigRepositoryImpl.java @@ -8,10 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; @Repository @@ -34,7 +31,10 @@ public class PermissionConfigRepositoryImpl implements PermissionConfigRepositor @Override public List findByPermissionNameIn(Set approvalTypes) { List permissionConfigs = cachePermissionConfigRepository - .cachePermissionConfigBatch(approvalTypes); + .cachePermissionConfigBatch(approvalTypes) + .stream() + .filter(Objects::nonNull) + .toList(); List cachedNames = permissionConfigs.stream() .filter(Objects::nonNull) .map(PermissionConfig::getPermissionName) @@ -45,7 +45,10 @@ public class PermissionConfigRepositoryImpl implements PermissionConfigRepositor .toList(); if (!missingNames.isEmpty()) { List fetchedPermissionConfigs = jdbcPermissionConfigRepository - .findByPermissionNameIn(missingNames); + .findByPermissionNameIn(missingNames) + .stream() + .filter(Objects::nonNull).toList(); + permissionConfigs = new ArrayList<>(permissionConfigs); permissionConfigs.addAll(fetchedPermissionConfigs); CompletableFuture.runAsync(() -> fetchedPermissionConfigs.forEach(this::updateCache)); } diff --git a/src/main/java/com/chint/infrastructure/repository/cache/CachePermissionConfigRepository.java b/src/main/java/com/chint/infrastructure/repository/cache/CachePermissionConfigRepository.java index 34d0f209..03d15bff 100644 --- a/src/main/java/com/chint/infrastructure/repository/cache/CachePermissionConfigRepository.java +++ b/src/main/java/com/chint/infrastructure/repository/cache/CachePermissionConfigRepository.java @@ -6,21 +6,33 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; @Repository public class CachePermissionConfigRepository { @Autowired - private RedisTemplate redisTemplate; + private RedisTemplate redisTemplate; public List cachePermissionConfigBatch(Set permissionNameList) { List keys = permissionNameList.stream() .filter(Objects::nonNull) .map(name -> "PermissionConfig::" + name).toList(); - return redisTemplate.opsForValue().multiGet(keys); + List rawConfigs = redisTemplate.opsForValue().multiGet(keys); + if (rawConfigs == null) { + return Collections.emptyList(); + } + + List permissionConfigs = rawConfigs.stream() + .filter(config -> config instanceof PermissionConfig) + .map(config -> (PermissionConfig) config) + .collect(Collectors.toList()); + + return Objects.requireNonNull(permissionConfigs); } @Cacheable(value = "PermissionConfig", key = "#permissionConfig.permissionName") diff --git a/src/main/java/com/chint/infrastructure/util/DelayDispatch.java b/src/main/java/com/chint/infrastructure/util/DelayDispatch.java index fa499f43..51c0bcf6 100644 --- a/src/main/java/com/chint/infrastructure/util/DelayDispatch.java +++ b/src/main/java/com/chint/infrastructure/util/DelayDispatch.java @@ -11,7 +11,11 @@ public class DelayDispatch { if (attempt >= 5) { return; } - boolean success = requestSupplier != null && requestSupplier.get() != null && requestSupplier.get(); // 使用Supplier获取请求成功与否的状态 + boolean success = false; + if (requestSupplier != null) { + Boolean result = requestSupplier.get(); + success = result != null && result; + } if (!success) { ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.schedule(() -> { @@ -23,4 +27,4 @@ public class DelayDispatch { }, 5, TimeUnit.SECONDS); } } -} +} \ No newline at end of file