凭证下载审计优化

This commit is contained in:
2026-08-11 12:04:22 +08:00 Unverified
parent 5ab980c623
commit bf01dba72b
3 changed files with 39 additions and 6 deletions
@@ -606,7 +606,7 @@ public sealed record EvaluationScoreRequest(
public sealed record TeacherEvaluationTaskResult( public sealed record TeacherEvaluationTaskResult(
Guid SetupId, Guid SetupId,
string Name, string SetupName,
TeacherEvaluationTask Task, TeacherEvaluationTask Task,
int StudentCount, int StudentCount,
double AverageTotal, double AverageTotal,
@@ -227,14 +227,24 @@ public sealed class OfficialDocumentsController(
[Authorize(Roles = Managers)] [Authorize(Roles = Managers)]
public async Task<ActionResult> DownloadHistory( public async Task<ActionResult> DownloadHistory(
Guid id, Guid id,
CancellationToken cancellationToken) CancellationToken cancellationToken,
int page = 1,
int pageSize = 20)
{ {
if (page < 1 || pageSize is < 1 or > 100)
return ValidationProblem("页码必须大于 0,且每页条数应在 1 至 100 之间。");
if (!await AccessibleDocuments().AnyAsync(x => x.Id == id, cancellationToken)) if (!await AccessibleDocuments().AnyAsync(x => x.Id == id, cancellationToken))
return NotFound(); return NotFound();
return Ok(await db.OfficialDocumentDownloads.AsNoTracking() var source = db.OfficialDocumentDownloads.AsNoTracking()
.Where(x => x.OfficialDocumentId == id) .Where(x => x.OfficialDocumentId == id)
.OrderByDescending(x => x.CreatedAt) .OrderByDescending(x => x.CreatedAt)
.ThenByDescending(x => x.Id);
var total = await source.CountAsync(cancellationToken);
var items = await source
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(x => new .Select(x => new
{ {
x.Id, x.Id,
@@ -244,7 +254,8 @@ public sealed class OfficialDocumentsController(
x.IpAddress, x.IpAddress,
x.UserAgent x.UserAgent
}) })
.ToListAsync(cancellationToken)); .ToListAsync(cancellationToken);
return Ok(new PagedResult<object>(items, total, page, pageSize));
} }
[HttpPost("{id:guid}/invalidate")] [HttpPost("{id:guid}/invalidate")]
+24 -2
View File
@@ -49,6 +49,9 @@ const issueDialog = ref(false)
const historyDrawer = ref(false) const historyDrawer = ref(false)
const historyLoading = ref(false) const historyLoading = ref(false)
const downloadHistory = ref<any[]>([]) const downloadHistory = ref<any[]>([])
const historyPage = ref(1)
const historyTotal = ref(0)
const historyPageSize = 20
const selectedDocument = ref<OfficialDocumentRow>() const selectedDocument = ref<OfficialDocumentRow>()
const filters = reactive<{ type?: DocumentType; status?: DocumentStatus }>({}) const filters = reactive<{ type?: DocumentType; status?: DocumentStatus }>({})
const page = ref(1) const page = ref(1)
@@ -192,10 +195,20 @@ async function reissue(row: OfficialDocumentRow) {
async function showHistory(row: OfficialDocumentRow) { async function showHistory(row: OfficialDocumentRow) {
selectedDocument.value = row selectedDocument.value = row
historyDrawer.value = true historyDrawer.value = true
historyPage.value = 1
await loadHistory()
}
async function loadHistory() {
if (!selectedDocument.value) return
historyLoading.value = true historyLoading.value = true
try { try {
const { data } = await http.get(`/official-documents/${row.id}/downloads`) const { data } = await http.get(
downloadHistory.value = data `/official-documents/${selectedDocument.value.id}/downloads`,
{ params: { page: historyPage.value, pageSize: historyPageSize } },
)
downloadHistory.value = data.items
historyTotal.value = data.total
} catch (error) { } catch (error) {
ElMessage.error(apiErrorMessage(error)) ElMessage.error(apiErrorMessage(error))
} finally { } finally {
@@ -355,6 +368,15 @@ onMounted(load)
<el-table-column label="来源 IP" prop="ipAddress" min-width="130" /> <el-table-column label="来源 IP" prop="ipAddress" min-width="130" />
</el-table> </el-table>
<el-empty v-if="!historyLoading && !downloadHistory.length" description="尚无下载记录" /> <el-empty v-if="!historyLoading && !downloadHistory.length" description="尚无下载记录" />
<el-pagination
v-if="historyTotal > historyPageSize"
v-model:current-page="historyPage"
:page-size="historyPageSize"
:total="historyTotal"
layout="total, prev, pager, next"
class="document-pagination"
@current-change="loadHistory"
/>
</el-drawer> </el-drawer>
</div> </div>
</template> </template>