凭证下载审计优化
This commit is contained in:
@@ -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")]
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user