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.*; import java.util.stream.Collectors; @Service public class AppointmentContainerService { private final AppointmentContainerMapper mapper; private final AppointmentWarehouseClient warehouses; private final String token; public AppointmentContainerService(AppointmentContainerMapper 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 keyword) { if(page<1 || size<1 || size>100 || keyword!=null && keyword.length()>128) throw bad("分页或搜索条件无效"); var catalog=catalog(); if(catalog.isEmpty()) return new PageResult<>(List.of(),page,size,0,0); var origins=List.copyOf(catalog.keySet()); keyword=clean(keyword); long total=mapper.count(origins,keyword,null); var rows=total==0 ? List.of() : mapper.page(origins,keyword,null,size,(long)(page-1)*size); attachWarehouses(rows,catalog); return new PageResult<>(rows,page,size,total,(total+size-1)/size); } public AppointmentContainer.Context context(String containerId,String warehouseId) { subjectKey(containerId,warehouseId); var catalog=catalog(); var rows=catalog.isEmpty() ? List.of() : mapper.page(List.copyOf(catalog.keySet()),null,containerId,1,0); if(rows.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND,"未找到美国范围内已开船的有效柜次"); attachWarehouses(rows,catalog); var row=rows.get(0); String warehouseName=null; if(warehouseId!=null) warehouseName=row.getWarehouses().stream().filter(w->w.warehouseId().equals(warehouseId)) .map(AppointmentContainer.Warehouse::warehouseName).findFirst().orElseThrow(()->bad("该接仓点不属于当前柜次")); return new AppointmentContainer.Context(containerId,row.getContainerNo(),warehouseId,warehouseName, !row.isIncompleteScope(),row.isIncompleteScope()?List.of("同柜仍有未明确或非美国接仓点,请先核对整柜范围"):List.of()); } public static String subjectKey(String containerId,String warehouseId) { if(containerId==null || !containerId.matches("[A-Za-z0-9_-]{1,64}") || warehouseId!=null && !warehouseId.matches("[0-9]{1,20}")) throw bad("柜次或接仓点标识无效"); return "CONTAINER:"+containerId+(warehouseId==null?"":":WAREHOUSE:"+warehouseId); } private void attachWarehouses(List rows,Map catalog) { if(rows.isEmpty()) return; var groups=mapper.warehouses(List.copyOf(catalog.keySet()),rows.stream().map(AppointmentContainer::getContainerBookingId).toList()).stream() .collect(Collectors.groupingBy(AppointmentContainerMapper.WarehouseCount::containerBookingId)); for(var row:rows) row.setWarehouses(groups.getOrDefault(row.getContainerBookingId(),List.of()).stream() .map(w->new AppointmentContainer.Warehouse(w.containerBookingId(),w.warehouseId(),catalog.get(w.warehouseId()).warehouseName(),w.orderCount(),w.customerCount())).toList()); } private Map catalog() { try { var response=warehouses.catalog(token); if(response==null || !response.successful() || response.data()==null) throw new IllegalStateException(); var result=new LinkedHashMap(); for(var w:response.data()) if(w!=null && w.id()!=null && w.id()>0 && "US".equals(w.countryCode()) && Set.of("OVERSEAS","OVERSEAS_PARTNER").contains(Objects.toString(w.warehouseType(),""))) result.put(w.id().toString(),w); return result; } catch(RuntimeException error) { throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,"仓库目录暂不可用,无法核对美国整柜范围",error); } } private static String clean(String value) { return value==null || value.isBlank()?null:value.trim(); } private static ResponseStatusException bad(String message) { return new ResponseStatusException(HttpStatus.BAD_REQUEST,message); } }