游标分页优化
This commit is contained in:
1 parent
f5db2f6e77
commit
0a0713e65b
17 files changed
+448
-156
No files matched your search
@@ -30,8 +30,8 @@ public sealed class TeachingTasksController(
|
||||
SystemRoles.AcademicAdmin;
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PagedResult<object>>> Get(
|
||||
int page = 1,
|
||||
public async Task<ActionResult<CursorPagedResult<object>>> Get(
|
||||
string? cursor = null,
|
||||
int pageSize = 20,
|
||||
string? keyword = null,
|
||||
Guid? academicTermId = null,
|
||||
@@ -41,8 +41,9 @@ public sealed class TeachingTasksController(
|
||||
string? teacherKeyword = null,
|
||||
string? classKeyword = null)
|
||||
{
|
||||
page = Math.Max(1, page);
|
||||
pageSize = Math.Clamp(pageSize, 10, 100);
|
||||
if (!CursorToken.TryDecode<TaskCursor>(cursor, out var after))
|
||||
return BadRequest("教学任务游标无效。");
|
||||
var source = ScopedTasks().AsNoTracking();
|
||||
if (academicTermId.HasValue)
|
||||
source = source.Where(x => x.AcademicTermId == academicTermId);
|
||||
@@ -75,11 +76,18 @@ public sealed class TeachingTasksController(
|
||||
}
|
||||
|
||||
var total = await source.CountAsync(cancellationToken);
|
||||
var items = await source
|
||||
if (after is not null)
|
||||
{
|
||||
source = source.Where(x => x.AcademicTerm!.StartDate < after.TermStartDate ||
|
||||
x.AcademicTerm.StartDate == after.TermStartDate &&
|
||||
(x.TaskNumber.CompareTo(after.TaskNumber) > 0 ||
|
||||
x.TaskNumber == after.TaskNumber && x.Id.CompareTo(after.Id) > 0));
|
||||
}
|
||||
var rows = await source
|
||||
.OrderByDescending(x => x.AcademicTerm!.StartDate)
|
||||
.ThenBy(x => x.TaskNumber)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ThenBy(x => x.Id)
|
||||
.Take(pageSize + 1)
|
||||
.Select(x => new
|
||||
{
|
||||
x.Id,
|
||||
@@ -87,6 +95,7 @@ public sealed class TeachingTasksController(
|
||||
x.Name,
|
||||
x.AcademicTermId,
|
||||
TermName = x.AcademicTerm!.Name,
|
||||
TermStartDate = x.AcademicTerm.StartDate,
|
||||
x.CourseId,
|
||||
CourseCode = x.Course!.Code,
|
||||
CourseName = x.Course.Name,
|
||||
@@ -114,9 +123,17 @@ public sealed class TeachingTasksController(
|
||||
x.UpdatedAt
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
return Ok(new PagedResult<object>(items, total, page, pageSize));
|
||||
var hasMore = rows.Count > pageSize;
|
||||
var items = rows.Take(pageSize).ToArray();
|
||||
var last = items.LastOrDefault();
|
||||
return Ok(new CursorPagedResult<object>(items.Cast<object>().ToArray(),
|
||||
hasMore && last is not null
|
||||
? CursorToken.Encode(new TaskCursor(last.TermStartDate, last.TaskNumber, last.Id)) : null,
|
||||
hasMore, pageSize, total));
|
||||
}
|
||||
|
||||
private sealed record TaskCursor(DateOnly TermStartDate, string TaskNumber, Guid Id);
|
||||
|
||||
[HttpGet("options")]
|
||||
public async Task<ActionResult> GetOptions(
|
||||
Guid academicTermId,
|
||||
|
||||
Reference in new issue
Block a user