优化
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
package com.baiyue.firstleg.controller;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.firstleg.dto.LoadingAssociationDtos.Summary;
|
||||
import com.baiyue.firstleg.service.FirstlegScopeGuard;
|
||||
import com.baiyue.firstleg.service.LoadingAssociationQueryService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/platform/v1/first-leg/loading-associations")
|
||||
public class PlatformLoadingAssociationController {
|
||||
@Resource
|
||||
private LoadingAssociationQueryService service;
|
||||
|
||||
@GetMapping("/summary")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:smart-loading:list')")
|
||||
public ApiResponse<Summary> summary(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@RequestParam(required = false) @Positive Long inboundId,
|
||||
@RequestParam(required = false) @Size(max = 40) String inboundCode) {
|
||||
FirstlegScopeGuard.platform(user);
|
||||
return ApiResponse.success(service.summary(inboundId, inboundCode));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baiyue.firstleg.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Admin 统一关联抽屉使用的装柜/PDA只读业务摘要。 */
|
||||
public final class LoadingAssociationDtos {
|
||||
private LoadingAssociationDtos() {
|
||||
}
|
||||
|
||||
public record ItemReference(String itemId) {
|
||||
}
|
||||
|
||||
public record Summary(
|
||||
String inboundId,
|
||||
String inboundCode,
|
||||
String orderNo,
|
||||
String loadingPlanId,
|
||||
String loadingPlanNo,
|
||||
String containerBookingId,
|
||||
String cabinetNo,
|
||||
String containerNo,
|
||||
String loadingStatus,
|
||||
String taskId,
|
||||
String pdaTaskStatus,
|
||||
String coLoadGroupId,
|
||||
String coLoadGroupNo,
|
||||
List<ItemReference> items
|
||||
) {
|
||||
public Summary {
|
||||
items = items == null ? List.of() : List.copyOf(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.baiyue.firstleg.mapper;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Firstleg 单库内按入仓片段读取装柜、PDA与同柜组稳定关联。 */
|
||||
@Mapper
|
||||
public interface LoadingAssociationMapper {
|
||||
String SELECT_ASSOCIATIONS = """
|
||||
SELECT inbound.id inboundId,inbound.inbound_code inboundCode,inbound.order_no orderNo,
|
||||
item.id itemId,plan.id loadingPlanId,plan.plan_no loadingPlanNo,
|
||||
booking.id containerBookingId,booking.cabinet_no cabinetNo,
|
||||
booking.container_no containerNo,plan.plan_status loadingStatus,
|
||||
task.id taskId,
|
||||
CASE WHEN task.id IS NULL THEN NULL
|
||||
WHEN task.task_status='COMPLETED' THEN 'COMPLETED'
|
||||
WHEN task.task_status='COMPLETING' THEN 'PROCESSING'
|
||||
WHEN task.task_status='COMPLETION_FAILED' THEN 'COMPLETION_FAILED'
|
||||
WHEN assignment.pick_task_id IS NULL THEN 'UNASSIGNED'
|
||||
WHEN NOT EXISTS (SELECT 1 FROM fl_loading_pick_item unresolved
|
||||
WHERE unresolved.pick_task_id=task.id
|
||||
AND unresolved.item_status IN ('PENDING','PICKING'))
|
||||
THEN 'AWAITING_REVIEW'
|
||||
ELSE 'IN_PROGRESS' END pdaTaskStatus,
|
||||
group_row.id coLoadGroupId,group_row.group_no coLoadGroupNo
|
||||
FROM fl_inbound_order inbound
|
||||
LEFT JOIN fl_loading_plan_item item
|
||||
ON item.account_id=inbound.tenant_id AND item.inbound_id=inbound.id AND item.deleted=0
|
||||
LEFT JOIN fl_loading_plan plan ON plan.id=item.loading_plan_id
|
||||
LEFT JOIN fl_container_booking booking ON booking.id=plan.container_booking_id
|
||||
LEFT JOIN fl_loading_pick_task task ON task.loading_plan_id=plan.id
|
||||
LEFT JOIN fl_loading_pick_assignment assignment ON assignment.pick_task_id=task.id
|
||||
LEFT JOIN fl_coload_group_member group_member ON group_member.id=(
|
||||
SELECT MAX(member_latest.id) FROM fl_coload_group_member member_latest
|
||||
JOIN fl_coload_group group_latest ON group_latest.id=member_latest.group_id
|
||||
AND group_latest.group_status<>'CANCELLED'
|
||||
WHERE member_latest.tenant_id=inbound.tenant_id
|
||||
AND member_latest.inbound_id=inbound.id)
|
||||
LEFT JOIN fl_coload_group group_row ON group_row.id=group_member.group_id
|
||||
WHERE inbound.deleted=0
|
||||
""";
|
||||
|
||||
@Select(SELECT_ASSOCIATIONS + " AND inbound.id=#{inboundId} ORDER BY item.id")
|
||||
List<Row> byInboundId(@Param("inboundId") long inboundId);
|
||||
|
||||
@Select(SELECT_ASSOCIATIONS + " AND inbound.inbound_code=#{inboundCode} ORDER BY inbound.id,item.id")
|
||||
List<Row> byInboundCode(@Param("inboundCode") String inboundCode);
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
class Row {
|
||||
private Long inboundId;
|
||||
private String inboundCode;
|
||||
private String orderNo;
|
||||
private Long itemId;
|
||||
private Long loadingPlanId;
|
||||
private String loadingPlanNo;
|
||||
private Long containerBookingId;
|
||||
private String cabinetNo;
|
||||
private String containerNo;
|
||||
private String loadingStatus;
|
||||
private Long taskId;
|
||||
private String pdaTaskStatus;
|
||||
private Long coLoadGroupId;
|
||||
private String coLoadGroupNo;
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.baiyue.firstleg.service;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.dto.LoadingAssociationDtos.ItemReference;
|
||||
import com.baiyue.firstleg.dto.LoadingAssociationDtos.Summary;
|
||||
import com.baiyue.firstleg.mapper.LoadingAssociationMapper;
|
||||
import com.baiyue.firstleg.mapper.LoadingAssociationMapper.Row;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** 装柜关联只读查询;inboundCode解析和业务摘要编排均不改变现有写接口主键。 */
|
||||
@Service
|
||||
public class LoadingAssociationQueryService {
|
||||
@Resource
|
||||
private LoadingAssociationMapper mapper;
|
||||
|
||||
public Summary summary(Long inboundId, String inboundCode) {
|
||||
String code = StringUtils.hasText(inboundCode) ? inboundCode.trim() : null;
|
||||
if ((inboundId == null) == (code == null)) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "inboundId与inboundCode必须且只能提供一个");
|
||||
}
|
||||
if (inboundId != null && inboundId <= 0) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "inboundId必须大于0");
|
||||
}
|
||||
List<Row> rows = inboundId == null ? mapper.byInboundCode(code) : mapper.byInboundId(inboundId);
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "入仓片段不存在");
|
||||
}
|
||||
Row first = rows.get(0);
|
||||
requireSingleValue(rows.stream().map(Row::getInboundId).toList(), "inboundCode匹配多个入仓片段");
|
||||
requireSingleValue(rows.stream().map(Row::getLoadingPlanId).filter(Objects::nonNull).toList(),
|
||||
"同一入仓片段关联多个有效装柜计划");
|
||||
requireSingleValue(rows.stream().map(Row::getTaskId).filter(Objects::nonNull).toList(),
|
||||
"同一入仓片段关联多个PDA任务");
|
||||
requireSingleValue(rows.stream().map(Row::getCoLoadGroupId).filter(Objects::nonNull).toList(),
|
||||
"同一入仓片段关联多个有效同柜组");
|
||||
List<ItemReference> items = rows.stream().map(Row::getItemId).filter(Objects::nonNull).distinct()
|
||||
.sorted().map(String::valueOf).map(ItemReference::new).toList();
|
||||
return new Summary(id(first.getInboundId()), first.getInboundCode(), first.getOrderNo(),
|
||||
id(first.getLoadingPlanId()), first.getLoadingPlanNo(), id(first.getContainerBookingId()),
|
||||
first.getCabinetNo(), first.getContainerNo(), first.getLoadingStatus(), id(first.getTaskId()),
|
||||
first.getPdaTaskStatus(), id(first.getCoLoadGroupId()), first.getCoLoadGroupNo(), items);
|
||||
}
|
||||
|
||||
private static void requireSingleValue(List<Long> values, String message) {
|
||||
if (values.stream().distinct().limit(2).count() > 1) {
|
||||
throw new BizException(ResultCode.CONFLICT, message);
|
||||
}
|
||||
}
|
||||
|
||||
private static String id(Long value) {
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user