This commit is contained in:
2026-10-15 16:30:37 +08:00
parent c6bd6af5ce
commit 628b1a5732
5 changed files with 165 additions and 4 deletions
@@ -10,6 +10,13 @@ import java.util.List;
/** Immutable movements retain original return ownership when cartons are merged again. */
@Mapper
public interface ReturnPackingTraceMapper {
// Collapse fragments within one operation; separate physical operations remain separate history.
String HISTORY_SELECT = "SELECT JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo')) AS plan_no,"
+ "t.source_carton_mark,t.target_carton_mark,t.return_no,t.sku_code,SUM(t.quantity) AS quantity,"
+ "MIN(t.created_at) AS created_at FROM ll_return_packing_trace t "
+ "JOIN ll_return_inventory_operation o ON o.id=t.operation_id ";
String HISTORY_GROUP = " GROUP BY t.operation_id,JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo')),"
+ "t.source_carton_mark,t.target_carton_mark,t.return_no,t.sku_code ";
record Trace(long id, String sourceCartonMark, String targetCartonMark, String returnNo,
String skuCode, long quantity, LocalDateTime createdAt) { }
record Ownership(String returnNo, long quantity) { }
@@ -28,15 +35,18 @@ public interface ReturnPackingTraceMapper {
@Select("SELECT id,source_carton_mark,target_carton_mark,return_no,sku_code,quantity,created_at FROM ll_return_packing_trace WHERE customer_id=#{customerId} AND return_no=#{returnNo} ORDER BY created_at,id")
List<Trace> listReturn(@Param("customerId") String customerId, @Param("returnNo") String returnNo);
@Select("SELECT JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo')) AS plan_no,t.source_carton_mark,t.target_carton_mark,t.return_no,t.sku_code,t.quantity,t.created_at FROM ll_return_packing_trace t JOIN ll_return_inventory_operation o ON o.id=t.operation_id WHERE t.customer_id=#{customerId} AND t.return_no=#{returnNo} AND t.source_carton_mark<>'' ORDER BY t.created_at,t.id")
@Select(HISTORY_SELECT + "WHERE t.customer_id=#{customerId} AND t.return_no=#{returnNo} AND t.source_carton_mark<>''"
+ HISTORY_GROUP + "ORDER BY MIN(t.created_at),MIN(t.id)")
List<com.baiyue.lastleg.returnreceipt.dto.ReturnOrderResponses.PackingDetail> returnHistory(@Param("customerId") String customerId, @Param("returnNo") String returnNo);
@Select("SELECT JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo')) AS plan_no,t.source_carton_mark,t.target_carton_mark,t.return_no,t.sku_code,t.quantity,t.created_at FROM ll_return_packing_trace t JOIN ll_return_inventory_operation o ON o.id=t.operation_id WHERE t.customer_id=#{customerId} AND JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo'))=#{planNo} AND t.source_carton_mark<>'' ORDER BY t.created_at,t.id")
@Select(HISTORY_SELECT + "WHERE t.customer_id=#{customerId} AND JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo'))=#{planNo} AND t.source_carton_mark<>''"
+ HISTORY_GROUP + "ORDER BY MIN(t.created_at),MIN(t.id)")
List<com.baiyue.lastleg.returnreceipt.dto.ReturnInventoryResponses.MergeHistory> planHistory(@Param("customerId") String customerId, @Param("planNo") String planNo);
@Select("SELECT JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.operatorName')) FROM ll_return_inventory_operation o WHERE JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo'))=#{planNo} AND o.operation_type='MERGE' ORDER BY o.id LIMIT 1")
String planOperator(@Param("planNo") String planNo);
@Select("SELECT JSON_UNQUOTE(JSON_EXTRACT(o.result_json,'$.planNo')) AS plan_no,t.source_carton_mark,t.target_carton_mark,t.return_no,t.sku_code,t.quantity,t.created_at FROM ll_return_packing_trace t JOIN ll_return_inventory_operation o ON o.id=t.operation_id WHERE t.customer_id=#{customerId} AND o.operation_type='MERGE' AND t.source_carton_mark<>'' AND (t.source_carton_mark=#{mark} OR t.target_carton_mark=#{mark}) ORDER BY t.created_at DESC,t.id DESC")
@Select(HISTORY_SELECT + "WHERE t.customer_id=#{customerId} AND o.operation_type='MERGE' AND t.source_carton_mark<>'' AND (t.source_carton_mark=#{mark} OR t.target_carton_mark=#{mark})"
+ HISTORY_GROUP + "ORDER BY MIN(t.created_at) DESC,MIN(t.id) DESC")
List<com.baiyue.lastleg.returnreceipt.dto.ReturnInventoryResponses.MergeHistory> listCartonHistory(@Param("customerId") String customerId, @Param("mark") String mark);
}
@@ -1190,7 +1190,13 @@ public class ReturnInventoryService {
if (origins.length != 1) throw conflict("历史混箱缺少逐 SKU 来源明细,不能继续合并");
result.add(new com.baiyue.lastleg.returnreceipt.mapper.ReturnPackingTraceMapper.Ownership(origins[0], quantity - traced));
}
return result;
// Existing trace and the original untracked remainder can belong to the same return.
// Coalesce before checking for multiple owners or recording a new movement.
Map<String, Long> byReturn = new LinkedHashMap<>();
for (var origin : result) byReturn.merge(origin.returnNo(), origin.quantity(), Math::addExact);
return byReturn.entrySet().stream()
.map(entry -> new com.baiyue.lastleg.returnreceipt.mapper.ReturnPackingTraceMapper.Ownership(entry.getKey(), entry.getValue()))
.toList();
}
private ReturnInventoryResponses.MergeResult replayMerge(ReturnInventoryOperation operation, String requestHash) {