游标分页优化
This commit is contained in:
1 parent
f5db2f6e77
commit
0a0713e65b
17 files changed
+448
-156
No files matched your search
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Jiaowu.Api.Contracts;
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Domain.Identity;
|
||||
using Jiaowu.Api.Infrastructure.Auth;
|
||||
@@ -62,14 +63,15 @@ public sealed class DegreeAwardsController(
|
||||
[Authorize(Roles = Reviewers)]
|
||||
public async Task<ActionResult> GetBatch(
|
||||
Guid id,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] string? cursor = null,
|
||||
[FromQuery] int pageSize = 20,
|
||||
[FromQuery] string? keyword = null,
|
||||
[FromQuery] DegreeAwardConclusion? conclusion = null,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
page = Math.Max(page, 1);
|
||||
pageSize = Math.Clamp(pageSize, 10, 100);
|
||||
if (!CursorToken.TryDecode<DegreeResultCursor>(cursor, out var after))
|
||||
return BadRequest("学位授予结果游标无效。");
|
||||
var batch = await db.DegreeAwardBatches.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.Id == id, token);
|
||||
if (batch is null) return NotFound();
|
||||
@@ -104,9 +106,13 @@ public sealed class DegreeAwardsController(
|
||||
source = source.Where(x => x.Conclusion == conclusion.Value);
|
||||
|
||||
var total = await source.CountAsync(token);
|
||||
var items = await source.OrderBy(x => x.Student!.StudentNumber)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
if (after is not null)
|
||||
{
|
||||
source = source.Where(x => x.Student!.StudentNumber.CompareTo(after.StudentNumber) > 0 ||
|
||||
x.Student.StudentNumber == after.StudentNumber && x.Id.CompareTo(after.Id) > 0);
|
||||
}
|
||||
var rows = await source.OrderBy(x => x.Student!.StudentNumber).ThenBy(x => x.Id)
|
||||
.Take(pageSize + 1)
|
||||
.Select(x => new
|
||||
{
|
||||
x.Id,
|
||||
@@ -124,6 +130,9 @@ public sealed class DegreeAwardsController(
|
||||
x.ReviewComment,
|
||||
x.ReviewedAt
|
||||
}).ToListAsync(token);
|
||||
var hasMore = rows.Count > pageSize;
|
||||
var items = rows.Take(pageSize).ToArray();
|
||||
var last = items.LastOrDefault();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
@@ -144,12 +153,16 @@ public sealed class DegreeAwardsController(
|
||||
{
|
||||
Items = items,
|
||||
Total = total,
|
||||
Page = page,
|
||||
HasMore = hasMore,
|
||||
NextCursor = hasMore && last is not null
|
||||
? CursorToken.Encode(new DegreeResultCursor(last.StudentNumber, last.Id)) : null,
|
||||
PageSize = pageSize
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private sealed record DegreeResultCursor(string StudentNumber, Guid Id);
|
||||
|
||||
[HttpPost("batches")]
|
||||
[Authorize(Roles = Managers)]
|
||||
public async Task<ActionResult> Create(
|
||||
|
||||
Reference in new issue
Block a user