diff --git a/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImpl.java b/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImpl.java index fbfedc53..70c98a64 100644 --- a/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImpl.java +++ b/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImpl.java @@ -465,7 +465,7 @@ public class PracticeSessionServiceImpl implements PracticeSessionService { // ========== internal helpers ========== /** - * 从 provider 获取题目列表,按 questionId 稳定排序,取前 count 条。 + * 从 provider 获取题目列表。题集路由保留手工成员顺序;其他路由按 questionId 稳定排序。 * 所有筛选条件(含 nodeId)完整转发到 provider,不做客户端裁剪。 */ private List fetchAndOrderQuestions(String collectionId, String nodeId, @@ -501,8 +501,10 @@ public class PracticeSessionServiceImpl implements PracticeSessionService { throw exception(INSUFFICIENT_ELIGIBLE_QUESTIONS, 0, count); } - allQuestions.sort(Comparator.comparing(CatalogQuestionDTO::getId, Comparator.nullsLast(String::compareTo)) - .thenComparing(CatalogQuestionDTO::getContentVersion, Comparator.nullsLast(String::compareTo))); + if (collectionId == null || collectionId.isBlank()) { + allQuestions.sort(Comparator.comparing(CatalogQuestionDTO::getId, Comparator.nullsLast(String::compareTo)) + .thenComparing(CatalogQuestionDTO::getContentVersion, Comparator.nullsLast(String::compareTo))); + } if (allQuestions.size() > count) { allQuestions = allQuestions.subList(0, count); } diff --git a/yudao-module-education/src/test/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImplTest.java b/yudao-module-education/src/test/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImplTest.java index b84f09f9..67c06be3 100644 --- a/yudao-module-education/src/test/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImplTest.java +++ b/yudao-module-education/src/test/java/cn/iocoder/yudao/module/education/service/practice/PracticeSessionServiceImplTest.java @@ -67,6 +67,18 @@ public class PracticeSessionServiceImplTest extends PostgreSqlDbIntegrationTest assertEquals(0L, sessionMapper.selectCount()); } + @Test + void shouldPreserveCollectionMembershipOrder() { + when(provider.isEnabled()).thenReturn(true); + when(provider.listQuestions(eq("col-order"), isNull(), isNull(), isNull(), eq(1), eq(2))) + .thenReturn(pageResult(List.of(questionDTO("20", "v1", "Twenty"), questionDTO("10", "v1", "Ten")))); + when(provider.listQuestions(eq("col-order"), isNull(), isNull(), isNull(), eq(2), eq(2))) + .thenReturn(pageResult(List.of())); + PracticeSessionCreateReqVO req = createReq("uuid-order", "col-order", 2); + PracticeSessionRespVO resp = service.createPracticeSession(req, 100L, 1L); + assertEquals(List.of("20", "10"), resp.getQuestions().stream().map(q -> q.getQuestionId()).toList()); + } + @Test void shouldCreateSessionAndReturnQuestions() { when(provider.isEnabled()).thenReturn(true); @@ -82,8 +94,8 @@ public class PracticeSessionServiceImplTest extends PostgreSqlDbIntegrationTest assertNotNull(resp.getSessionId()); assertEquals("ACTIVE", resp.getStatus()); assertEquals(2, resp.getQuestions().size()); - assertEquals("q-001", resp.getQuestions().get(0).getQuestionId()); - assertEquals("q-002", resp.getQuestions().get(1).getQuestionId()); + assertEquals("q-002", resp.getQuestions().get(0).getQuestionId()); + assertEquals("q-001", resp.getQuestions().get(1).getQuestionId()); assertEquals(1, resp.getQuestions().get(0).getSequence()); assertEquals(2, resp.getQuestions().get(1).getSequence()); }