This commit is contained in:
2026-08-31 10:17:03 +08:00
parent aa583efa4a
commit bf1dc1f209
17 changed files with 354 additions and 142 deletions
@@ -0,0 +1,47 @@
package com.baiyue.firstleg.loading.coload.controller;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.InternalBatchQueryRequest;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.InternalOrderGroupInfo;
import com.baiyue.firstleg.loading.coload.service.ColoadGroupService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.List;
/** Order 聚合使用的内部同柜组端口,不是 Platform 页面协议。 */
@RestController
@RequestMapping("/internal/firstleg/v1/coload-groups")
public class InternalColoadGroupController {
private final ColoadGroupService service;
@Value("${baiyue.security.internal-service-token}")
private String expectedToken;
public InternalColoadGroupController(ColoadGroupService service) {
this.service = service;
}
@PostMapping("/batch-query")
public ApiResponse<List<InternalOrderGroupInfo>> batchQuery(
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
@Valid @RequestBody InternalBatchQueryRequest request) {
requireToken(token);
return ApiResponse.success(service.queryInternalByOrderIds(request.orderIds()));
}
private void requireToken(String token) {
if (token == null || !MessageDigest.isEqual(token.getBytes(StandardCharsets.UTF_8),
expectedToken.getBytes(StandardCharsets.UTF_8))) {
throw new BizException(ResultCode.FORBIDDEN, "内部服务令牌无效");
}
}
}
@@ -24,6 +24,12 @@ public final class ColoadGroupModels {
) {
}
/** 仅供 Order 服务聚合使用,不属于 Platform 页面识别契约。 */
public record InternalBatchQueryRequest(
@NotEmpty @Size(max = 200) List<@NotNull @Min(1) Long> orderIds
) {
}
public record Member(
long tenantId,
long orderId,
@@ -74,4 +80,8 @@ public final class ColoadGroupModels {
memberCount = members.size();
}
}
/** 内部服务聚合投影;技术标识不得透传为页面主展示。 */
public record InternalOrderGroupInfo(long orderId, GroupSnapshot group) {
}
}
@@ -108,6 +108,16 @@ public interface ColoadGroupMapper {
""")
List<MemberCodeRow> effectiveMemberCodes(@Param("groupId") long groupId);
@Select({"<script>", """
SELECT member.order_id orderId,member.group_id groupId
FROM fl_coload_group_member member
JOIN fl_coload_group group_row ON group_row.id=member.group_id
WHERE member.order_id IN
""", "<foreach collection='orderIds' item='orderId' open='(' separator=',' close=')'>",
"#{orderId}", "</foreach>",
"AND group_row.group_status&lt;&gt;'CANCELLED' ORDER BY member.order_id,group_row.created_at DESC", "</script>"})
List<OrderGroupLinkRow> linksByOrderIds(@Param("orderIds") List<Long> orderIds);
@Update("""
UPDATE fl_coload_group
SET group_status='CANCELLED',cancelled_by=#{operatorId},
@@ -60,6 +60,13 @@ public final class ColoadPersistenceRows {
private String inboundCode;
}
@Getter
@Setter
public static class OrderGroupLinkRow {
private Long orderId;
private Long groupId;
}
@Getter
@Setter
public static class CommandRow {
@@ -7,6 +7,7 @@ import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.GroupSnapshot;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.Member;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.BusinessMember;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.BusinessSummary;
import com.baiyue.firstleg.loading.coload.model.ColoadGroupModels.InternalOrderGroupInfo;
import com.baiyue.firstleg.loading.coload.persistence.ColoadGroupMapper;
import com.baiyue.firstleg.loading.coload.persistence.ColoadPersistenceRows.CommandRow;
import com.baiyue.firstleg.loading.coload.persistence.ColoadPersistenceRows.GroupRow;
@@ -114,6 +115,20 @@ public class ColoadGroupService implements ColoadGroupAssignmentPort {
return new BusinessSummary(status, members.size(), members);
}
@Transactional(readOnly = true)
public List<InternalOrderGroupInfo> queryInternalByOrderIds(List<Long> requestedOrderIds) {
List<Long> orderIds = normalizedOrderIds(requestedOrderIds, 1, 200);
Map<Long, InternalOrderGroupInfo> latest = new LinkedHashMap<>();
Map<Long, GroupSnapshot> groups = new LinkedHashMap<>();
for (var link : mapper.linksByOrderIds(orderIds)) {
if (latest.containsKey(link.getOrderId())) continue;
GroupSnapshot group = groups.computeIfAbsent(link.getGroupId(), this::requiredSnapshot);
if (!CURRENT_GROUP_STATUSES.contains(group.status())) continue;
latest.put(link.getOrderId(), new InternalOrderGroupInfo(link.getOrderId(), group));
}
return orderIds.stream().map(latest::get).filter(Objects::nonNull).toList();
}
@Override
@Transactional(readOnly = true)
public GroupSnapshot findByInbound(long tenantId, long inboundId) {