fix: keep fleet booking timestamps stable across persistent replay
This commit is contained in:
+12
-2
@@ -20,6 +20,8 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.Clock;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Currency;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Objects;
|
||||
@@ -38,15 +40,22 @@ public class FleetBookingService {
|
||||
private final FleetBookingIncomingGateway incoming;
|
||||
private final FleetBookingQuoteContext quoteContext;
|
||||
private final FleetQuoteCandidateService quotes;
|
||||
private final Clock clock;
|
||||
@jakarta.annotation.Resource private FleetPoolOrderBridge poolOrders;
|
||||
@jakarta.annotation.Resource private FleetDispatchPlanningGateway planning;
|
||||
@jakarta.annotation.Resource private FleetDispatchGateway dispatches;
|
||||
@jakarta.annotation.Resource private FleetCapacityOfferCommandMapper commands;
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
public FleetBookingService(FleetTripMapper trips,FleetBookingMapper bookings,FleetBookingReservations reservations,
|
||||
FleetTripService history,FleetTripExecutionService execution,FleetCustomerDirectory customers,ObjectMapper json,FleetBookingIncomingGateway incoming,
|
||||
FleetBookingQuoteContext quoteContext,FleetQuoteCandidateService quotes){
|
||||
this(trips,bookings,reservations,history,execution,customers,json,incoming,quoteContext,quotes,Clock.systemUTC());
|
||||
}
|
||||
FleetBookingService(FleetTripMapper trips,FleetBookingMapper bookings,FleetBookingReservations reservations,
|
||||
FleetTripService history,FleetTripExecutionService execution,FleetCustomerDirectory customers,ObjectMapper json,FleetBookingIncomingGateway incoming,
|
||||
FleetBookingQuoteContext quoteContext,FleetQuoteCandidateService quotes,Clock clock){
|
||||
this.trips=trips;this.bookings=bookings;this.reservations=reservations;this.history=history;this.execution=execution;this.customers=customers;this.json=json;this.incoming=incoming;
|
||||
this.quoteContext=quoteContext;this.quotes=quotes;
|
||||
this.quoteContext=quoteContext;this.quotes=quotes;this.clock=clock;
|
||||
}
|
||||
public java.util.Map<FleetBookingIncomingGateway.Source,String> incomingStatuses(java.util.List<FleetBookingEntity> rows) {
|
||||
return incoming.statuses(rows.stream().filter(r->r.getIncomingNo()!=null).map(r->new FleetBookingIncomingGateway.Source(r.getCustomerId(),r.getIncomingNo())).distinct().toList());
|
||||
@@ -305,7 +314,8 @@ public class FleetBookingService {
|
||||
private String write(Object value){try{return json.writeValueAsString(value);}catch(Exception error){throw new IllegalStateException(error);}}
|
||||
/** 请求对象排除重放元数据;排车来源键的数组必须保留全部元素及顺序。 */
|
||||
private String hash(Object value){try{com.fasterxml.jackson.databind.JsonNode node=json.valueToTree(value);if(node instanceof ObjectNode object){object.remove("idempotencyKey");object.remove("tripRecordVersion");}return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(write(node).getBytes(StandardCharsets.UTF_8)));}catch(Exception error){throw new IllegalStateException(error);}}
|
||||
private static LocalDateTime now(){return LocalDateTime.now(ZoneOffset.UTC);}
|
||||
/** DATETIME(3)持久化前固定毫秒精度,首次回执与重新读取后的幂等重放保持同一时间事实。 */
|
||||
private LocalDateTime now(){return LocalDateTime.ofInstant(clock.instant(),ZoneOffset.UTC).truncatedTo(ChronoUnit.MILLIS);}
|
||||
private static String trim(String value){return value==null||value.isBlank()?null:value.trim();}
|
||||
private static String reason(String value,String fallback){return trim(value)==null?fallback:trim(value);}
|
||||
private static ResponseStatusException conflict(String value){return new ResponseStatusException(HttpStatus.CONFLICT,value);}
|
||||
|
||||
Reference in New Issue
Block a user