package com.baiyue.lastleg.appointmentplanning; import com.baiyue.common.core.api.PageResult; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; import java.util.List; import java.util.Set; @Service public class AppointmentCargoService { private final AppointmentCargoMapper mapper; private final AppointmentWarehouseClient warehouses; private final String token; public AppointmentCargoService(AppointmentCargoMapper mapper, AppointmentWarehouseClient warehouses, @Value("${baiyue.security.internal-service-token:}") String token) { this.mapper = mapper; this.warehouses = warehouses; this.token = token; } public PageResult page(int page, int size, String warehouseId, String destination, String keyword) { if (page < 1 || size < 1 || size > 100) throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "每页数量必须为1至100"); if (keyword != null && keyword.length() > 128) throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "搜索词过长"); var scope = scope(); var origins = scope.origins(); var destinations = scope.destinations(); warehouseId = clean(warehouseId); destination = clean(destination); keyword = clean(keyword); if (warehouseId != null && !origins.contains(warehouseId) || destination != null && !destinations.contains(destination)) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "请选择已启用的美国接仓点及FBA目的仓"); } if (origins.isEmpty() || destinations.isEmpty()) return new PageResult<>(List.of(), page, size, 0, 0); long total = mapper.count(origins, destinations, warehouseId, destination, keyword); var rows = mapper.page(origins, destinations, warehouseId, destination, keyword, size, (long) (page - 1) * size); return new PageResult<>(rows, page, size, total, (total + size - 1) / size); } private record Scope(List origins, List destinations) { } private Scope scope() { final List catalog; try { var result = warehouses.catalog(token); if (result == null || !result.successful() || result.data() == null) throw new IllegalStateException(); catalog = result.data(); } catch (RuntimeException error) { throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "仓库目录暂不可用,无法核实美国货物范围", error); } var us = catalog.stream().filter(w -> w != null && w.id() != null && w.id() > 0 && "US".equals(w.countryCode())).toList(); var origins = us.stream().filter(w -> Set.of("OVERSEAS", "OVERSEAS_PARTNER").contains(w.warehouseType() == null ? "" : w.warehouseType())) .map(w -> w.id().toString()).distinct().toList(); var destinations = us.stream().filter(w -> "FBA".equals(w.warehouseType()) && clean(w.warehouseCode()) != null) .map(AppointmentWarehouseClient.Warehouse::warehouseCode).distinct().toList(); return new Scope(origins, destinations); } private static String clean(String value) { return value == null || value.isBlank() ? null : value.trim(); } }