diff --git a/src/Jiaowu.Api/Controllers/OfficialDocumentsController.cs b/src/Jiaowu.Api/Controllers/OfficialDocumentsController.cs index 784fdb1..42b80c7 100644 --- a/src/Jiaowu.Api/Controllers/OfficialDocumentsController.cs +++ b/src/Jiaowu.Api/Controllers/OfficialDocumentsController.cs @@ -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; @@ -32,15 +33,24 @@ public sealed class OfficialDocumentsController( OfficialDocumentType? type, OfficialDocumentStatus? status, Guid? studentId, - CancellationToken cancellationToken) + CancellationToken cancellationToken, + int page = 1, + int pageSize = 20) { + if (page < 1 || pageSize is < 1 or > 100) + return ValidationProblem("页码必须大于 0,且每页条数应在 1 至 100 之间。"); + var source = AccessibleDocuments().AsNoTracking(); if (type.HasValue) source = source.Where(x => x.Type == type); if (status.HasValue) source = source.Where(x => x.Status == status); if (studentId.HasValue) source = source.Where(x => x.StudentId == studentId); - return Ok(await source + var total = await source.CountAsync(cancellationToken); + var items = await source .OrderByDescending(x => x.IssuedAt) + .ThenByDescending(x => x.Id) + .Skip((page - 1) * pageSize) + .Take(pageSize) .Select(x => new { x.Id, @@ -62,7 +72,8 @@ public sealed class OfficialDocumentsController( DownloadCount = x.Downloads.Count, LastDownloadedAt = x.Downloads.Max(download => (DateTime?)download.CreatedAt) }) - .ToListAsync(cancellationToken)); + .ToListAsync(cancellationToken); + return Ok(new PagedResult(items, total, page, pageSize)); } [HttpGet("students/options")] diff --git a/web/src/views/OfficialDocumentsView.vue b/web/src/views/OfficialDocumentsView.vue index 6be86de..601d374 100644 --- a/web/src/views/OfficialDocumentsView.vue +++ b/web/src/views/OfficialDocumentsView.vue @@ -51,6 +51,9 @@ const historyLoading = ref(false) const downloadHistory = ref([]) const selectedDocument = ref() const filters = reactive<{ type?: DocumentType; status?: DocumentStatus }>({}) +const page = ref(1) +const total = ref(0) +const pageSize = 20 const issueForm = reactive<{ studentId: string; type: DocumentType; purpose: string }>({ studentId: '', type: 'Transcript', @@ -67,11 +70,19 @@ const statusLabels: Record = { Superseded: '已重签', } -async function load() { +async function load(resetPage = false) { + if (resetPage) page.value = 1 loading.value = true try { - const { data } = await http.get('/official-documents', { params: filters }) - documents.value = data + const { data } = await http.get('/official-documents', { + params: { ...filters, page: page.value, pageSize }, + }) + documents.value = data.items + total.value = data.total + if (documents.value.length === 0 && page.value > 1) { + page.value-- + await load() + } } catch (error) { ElMessage.error(apiErrorMessage(error)) } finally { @@ -224,14 +235,14 @@ onMounted(load)
- + - + - 刷新 - 共 {{ documents.length }} 份凭证 + 刷新 + 共 {{ total }} 份凭证
@@ -274,6 +285,15 @@ onMounted(load) v-if="!documents.length" :description="isManager ? '暂无符合条件的官方凭证' : '暂无电子凭证,可点击上方按钮在线申请'" /> +